diff options
Diffstat (limited to '')
-rw-r--r-- | dom/security/test/general/test_block_toplevel_data_navigation.html | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/dom/security/test/general/test_block_toplevel_data_navigation.html b/dom/security/test/general/test_block_toplevel_data_navigation.html new file mode 100644 index 0000000000..bbadacb218 --- /dev/null +++ b/dom/security/test/general/test_block_toplevel_data_navigation.html @@ -0,0 +1,134 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Bug 1331351 - Block top level window data: URI navigations</title> + <!-- Including SimpleTest.js so we can use waitForExplicitFinish !--> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<script class="testbody" type="text/javascript"> + +async function expectBlockedToplevelData() { + await SpecialPowers.spawnChrome([], async () => { + let progressListener; + let bid = await new Promise(resolve => { + let bcs = []; + progressListener = { + QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]), + onStateChange(webProgress, request, stateFlags, status) { + if (!(request instanceof Ci.nsIChannel) || !webProgress.isTopLevel || + !(stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) || + !(stateFlags & Ci.nsIWebProgressListener.STATE_STOP)) { + return; + } + + if (!["NS_ERROR_DOM_BAD_URI", "NS_ERROR_CORRUPTED_CONTENT"].includes(ChromeUtils.getXPCOMErrorName(status))) { + info(ChromeUtils.getXPCOMErrorName(status)); + isnot(request.URI.scheme, "data"); + return; + } + + // We can't check for the scheme to be "data" because in the case of a + // redirected load, we'll get a `NS_ERROR_DOM_BAD_URI` load error + // before observing the redirect, cancelling the load. Instead we just + // wait for any load to error with `NS_ERROR_DOM_BAD_URI`. + for (let bc of bcs) { + try { + bc.webProgress.removeProgressListener(progressListener); + } catch(e) { } + } + bcs = []; + Services.obs.removeObserver(observer, "browsing-context-attached"); + resolve(webProgress.browsingContext.browserId); + } + }; + + function observer(subject, topic) { + if (!bcs.includes(subject.webProgress)) { + bcs.push(subject.webProgress); + subject.webProgress.addProgressListener(progressListener, Ci.nsIWebProgress.NOTIFY_ALL); + } + } + Services.obs.addObserver(observer, "browsing-context-attached"); + }); + return bid; + }); +} + +async function expectBlockedURIWarning() { + await SpecialPowers.spawnChrome([], async () => { + return new Promise(resolve => { + Services.console.registerListener(function onConsoleMessage(msg) { + info("Seeing console message: " + msg.message); + if (!(msg instanceof Ci.nsIScriptError)) { + return; + } + if (msg.category != "DATA_URI_BLOCKED") { + return; + } + + Services.console.unregisterListener(onConsoleMessage); + resolve(); + }); + }); + }); +} + +async function expectBrowserDiscarded(browserId) { + await SpecialPowers.spawnChrome([browserId], async (browserId) => { + return new Promise(resolve => { + function check() { + if (!BrowsingContext.getCurrentTopByBrowserId(browserId)) { + ok(true, `BrowserID ${browserId} discarded`); + resolve(); + Services.obs.removeObserver(check, "browsing-context-discarded"); + } + } + Services.obs.addObserver(check, "browsing-context-discarded"); + check(); + }); + }); +} + +async function popupTest(uri, expectClose) { + info(`Running expect blocked test for ${uri}`); + let reqBlockedPromise = expectBlockedToplevelData(); + let warningPromise = expectBlockedURIWarning(); + let win = window.open(uri); + let browserId = await reqBlockedPromise; + await warningPromise; + if (expectClose) { + await expectBrowserDiscarded(browserId); + } + win.close(); +} + +add_task(async function() { + await SpecialPowers.pushPrefEnv({ + set: [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + + // simple data: URI click navigation should be prevented + await popupTest("file_block_toplevel_data_navigation.html", false); + + // data: URI in iframe which opens data: URI in _blank should be blocked + await popupTest("file_block_toplevel_data_navigation2.html", false); + + // navigating to a data: URI using window.location.href should be blocked + await popupTest("file_block_toplevel_data_navigation3.html", false); + + // navigating to a data: URI using window.open() should be blocked + await popupTest("data:text/html,<body>toplevel data: URI navigations should be blocked</body>", false); + + // navigating to a URI which redirects to a data: URI using window.open() should be blocked + await popupTest("file_block_toplevel_data_redirect.sjs", false); + + // navigating to a data: URI without a Content Type should be blocked + await popupTest("data:,DataURIsWithNoContentTypeShouldBeBlocked", false); +}); + +</script> +</body> +</html> |