test_block_toplevel_data_navigation.html (4836B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Bug 1331351 - Block top level window data: URI navigations</title> 6 <!-- Including SimpleTest.js so we can use waitForExplicitFinish !--> 7 <script src="/tests/SimpleTest/SimpleTest.js"></script> 8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 9 </head> 10 <body> 11 <script class="testbody" type="text/javascript"> 12 13 async function expectBlockedToplevelData() { 14 await SpecialPowers.spawnChrome([], async () => { 15 let progressListener; 16 let bid = await new Promise(resolve => { 17 let bcs = []; 18 progressListener = { 19 QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]), 20 onStateChange(webProgress, request, stateFlags, status) { 21 if (!(request instanceof Ci.nsIChannel) || !webProgress.isTopLevel || 22 !(stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) || 23 !(stateFlags & Ci.nsIWebProgressListener.STATE_STOP)) { 24 return; 25 } 26 27 if (!["NS_ERROR_DOM_BAD_URI", "NS_ERROR_CORRUPTED_CONTENT", "NS_ERROR_ABORT"].includes(ChromeUtils.getXPCOMErrorName(status))) { 28 info(ChromeUtils.getXPCOMErrorName(status)); 29 isnot(request.URI.scheme, "data"); 30 return; 31 } 32 33 // We can't check for the scheme to be "data" because in the case of a 34 // redirected load, we'll get a `NS_ERROR_DOM_BAD_URI` load error 35 // before observing the redirect, cancelling the load. Instead we just 36 // wait for any load to error with `NS_ERROR_DOM_BAD_URI`. 37 for (let bc of bcs) { 38 try { 39 bc.webProgress.removeProgressListener(progressListener); 40 } catch(e) { } 41 } 42 bcs = []; 43 Services.obs.removeObserver(observer, "browsing-context-attached"); 44 resolve(webProgress.browsingContext.browserId); 45 } 46 }; 47 48 function observer(subject) { 49 if (!bcs.includes(subject.webProgress)) { 50 bcs.push(subject.webProgress); 51 subject.webProgress.addProgressListener(progressListener, Ci.nsIWebProgress.NOTIFY_ALL); 52 } 53 } 54 Services.obs.addObserver(observer, "browsing-context-attached"); 55 }); 56 return bid; 57 }); 58 } 59 60 async function expectBlockedURIWarning() { 61 await SpecialPowers.spawnChrome([], async () => { 62 return new Promise(resolve => { 63 Services.console.registerListener(function onConsoleMessage(msg) { 64 info("Seeing console message: " + msg.message); 65 if (!(msg instanceof Ci.nsIScriptError)) { 66 return; 67 } 68 if (msg.category != "DATA_URI_BLOCKED") { 69 return; 70 } 71 72 Services.console.unregisterListener(onConsoleMessage); 73 resolve(); 74 }); 75 }); 76 }); 77 } 78 79 async function expectBrowserDiscarded(browserId) { 80 await SpecialPowers.spawnChrome([browserId], async (browserId) => { 81 return new Promise(resolve => { 82 function check() { 83 if (!BrowsingContext.getCurrentTopByBrowserId(browserId)) { 84 ok(true, `BrowserID ${browserId} discarded`); 85 resolve(); 86 Services.obs.removeObserver(check, "browsing-context-discarded"); 87 } 88 } 89 Services.obs.addObserver(check, "browsing-context-discarded"); 90 check(); 91 }); 92 }); 93 } 94 95 async function popupTest(uri, expectClose) { 96 info(`Running expect blocked test for ${uri}`); 97 let reqBlockedPromise = expectBlockedToplevelData(); 98 let warningPromise = expectBlockedURIWarning(); 99 let win = window.open(uri); 100 let browserId = await reqBlockedPromise; 101 await warningPromise; 102 if (expectClose) { 103 await expectBrowserDiscarded(browserId); 104 } 105 win.close(); 106 } 107 108 add_task(async function() { 109 await SpecialPowers.pushPrefEnv({ 110 set: [["security.data_uri.block_toplevel_data_uri_navigations", true]], 111 }); 112 113 // simple data: URI click navigation should be prevented 114 await popupTest("file_block_toplevel_data_navigation.html", false); 115 116 // data: URI in iframe which opens data: URI in _blank should be blocked 117 await popupTest("file_block_toplevel_data_navigation2.html", false); 118 119 // navigating to a data: URI using window.location.href should be blocked 120 await popupTest("file_block_toplevel_data_navigation3.html", false); 121 122 // navigating to a data: URI using window.open() should be blocked 123 await popupTest("data:text/html,<body>toplevel data: URI navigations should be blocked</body>", false); 124 125 // navigating to a URI which redirects to a data: URI using window.open() should be blocked 126 await popupTest("file_block_toplevel_data_redirect.sjs", false); 127 128 // navigating to a data: URI without a Content Type should be blocked 129 await popupTest("data:,DataURIsWithNoContentTypeShouldBeBlocked", false); 130 }); 131 132 </script> 133 </body> 134 </html>