Skip to content

Commit

Permalink
fix(privacy): FrameCheckWrapper.js given incorrect value for url comp…
Browse files Browse the repository at this point in the history
…arison (#27320)

* Fix url passed to `FrameCheckWrapper.js` to match window.origin. The `domainURL` is stripping `m`, `mobile`, and `www` subdomains which can cause our check to miss incorrectly.

* Unit test for new `URL.windowOriginURL`.
  • Loading branch information
StephenHeaps authored Jan 30, 2025
1 parent 05a3003 commit c9fc5bd
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ class ScriptFactory {
sourceWrapper = sourceWrapper.replacingOccurrences(of: "$<scriplet>", with: source)
sourceWrapper = sourceWrapper.replacingOccurrences(
of: "$<required_href>",
with: configuration.frameURL.domainURL.absoluteString
with: configuration.frameURL.windowOriginURL.absoluteString
)
// when `isMainFrame` is true, we still need to inject to all frames to handle `about:blank` first-party frames
resultingScript = WKUserScript(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,15 @@ extension URL {

return renderedString.bidiBaseDirection == .leftToRight
}

/// Matches what `window.origin` would return in javascript.
public var windowOriginURL: URL {
var components = URLComponents()
components.scheme = self.scheme
components.port = self.port
components.host = self.host
return components.url ?? self
}
}

extension InternalURL {
Expand Down
55 changes: 55 additions & 0 deletions ios/brave-ios/Tests/BraveSharedTests/URLExtensionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import Foundation
import Shared
import WebKit
import XCTest

class URLExtensionTests: XCTestCase {
Expand Down Expand Up @@ -135,4 +136,58 @@ class URLExtensionTests: XCTestCase {
embeddedURL
)
}

// Test that `windowOriginURL` returns the same value as `window.origin`.
@MainActor func testWindowOriginURL() async {
let testURLs = [
// multiple subdomains
(URL(string: "https://one.two.three.example.com")!, "https://one.two.three.example.com"),
// trailing slash
(URL(string: "https://example.com/")!, "https://example.com"),
// query
(URL(string: "https://www.example.com/?v=1234567")!, "https://www.example.com"),
// match
(URL(string: "https://www.example.com")!, "https://www.example.com"),
// punycode
(URL(string: "http://Дом.ru/")!, "http://xn--d1aqf.ru"),
// punycode
(URL(string: "http://Дoм.ru/")!, "http://xn--o-gtbz.ru"),
]

let webView = WKWebView()
for (value, expected) in testURLs {
do {
let expectation = XCTestExpectation(description: "didFinish")
let navigationDelegate = NavigationDelegate(didFinish: {
expectation.fulfill()
})
webView.navigationDelegate = navigationDelegate
webView.loadHTMLString("", baseURL: value)

// await load of html
await fulfillment(of: [expectation], timeout: 2)

guard let result = try await webView.evaluateJavaScript("window.origin") as? String else {
XCTFail("Expected a String result")
return
}
XCTAssertEqual(result, expected)
XCTAssertEqual(result, value.windowOriginURL.absoluteString)
} catch {
XCTFail("Expected a valid `window.origin`")
}
}
}
}

private class NavigationDelegate: NSObject, WKNavigationDelegate {
private var didFinish: () -> Void

init(didFinish: @escaping () -> Void) {
self.didFinish = didFinish
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
didFinish()
}
}

0 comments on commit c9fc5bd

Please sign in to comment.