test_initial_blank_doc_principal.html (4315B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Tests for the principal of initial about:blank documents</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> 8 </head> 9 <body> 10 <p id="display"></p> 11 <div id="content"></div> 12 <pre id="test"></pre> 13 </body> 14 15 <script> 16 function waitForEvent(name, target, checkFn = null) { 17 return new Promise(resolve => { 18 function listener(event) { 19 if (!checkFn || checkFn(event)) { 20 resolve(event); 21 if (checkFn) { 22 target.removeEventListener(name, listener); 23 } 24 } 25 } 26 target.addEventListener(name, listener, { once: !checkFn }); 27 }); 28 } 29 30 const testContent = document.getElementById("content"); 31 32 async function createSandboxedIframe(options = {}) { 33 const { srcdoc = "", waitLoad = true, extraSandbox = "" } = options; 34 35 const ifr = document.createElement("iframe"); 36 ifr.sandbox = `allow-scripts ${extraSandbox}`; 37 if (srcdoc) { 38 ifr.srcdoc = srcdoc; 39 } 40 41 const loaded = waitLoad ? waitForEvent("load", ifr) : null; 42 testContent.appendChild(ifr); 43 if (waitLoad) { 44 await loaded; 45 } 46 47 return { ifr, doc: SpecialPowers.wrap(ifr).contentDocument }; 48 } 49 50 // Tests 51 52 // We want to check that 53 // - initial about:blank documents load synchronously 54 // - without failing assertions in nsDocShell::IsAboutBlankLoadOntoInitialAboutBlank 55 // - while ending up with the right principal 56 57 async function test_sandboxed_iframe() { 58 // basic case: <iframe sandbox> 59 const { ifr, doc } = await createSandboxedIframe({ waitLoad: false }); 60 is(doc.readyState, "complete", "Sandboxed iframe loaded initial document synchronously"); 61 ok(doc.nodePrincipal.isNullPrincipal, "Sandboxed ifame has null principal"); 62 ifr.remove(); 63 } 64 65 async function test_nested_iframes() { 66 // Iframes nested in an isolated iframe 67 const { ifr } = await createSandboxedIframe({ 68 srcdoc: "<iframe id=first></iframe><iframe id=second sandbox>" 69 }); 70 71 await SpecialPowers.spawn(ifr, [], () => { 72 const origin = content.document.nodePrincipal.siteOrigin; 73 const first = content.document.getElementById("first"); 74 const second = content.document.getElementById("second"); 75 const firstPrincipal = SpecialPowers.wrap(first).contentDocument.nodePrincipal; 76 const secondPrincipal = SpecialPowers.wrap(second).contentDocument.nodePrincipal; 77 ok(secondPrincipal.siteOrigin != origin, "<iframe> is implicitly isolated"); 78 ok(secondPrincipal.siteOrigin != origin, "<iframe sandbox> is explicitly isolated"); 79 ok(firstPrincipal.siteOrigin != secondPrincipal.siteOrigin, 'nested iframes are isolated from each other'); 80 }); 81 82 ifr.remove(); 83 } 84 85 async function test_nested_iframes_crash() { 86 // This caused an assertion failure during development 87 // due to nsFrameLoader::Show being called for the nested frames before ReallyStartLoading 88 // and so they end up with the wrong principal on the initial document. 89 const { ifr } = await createSandboxedIframe({ 90 srcdoc: "<iframe id=first></iframe><iframe id=second sandbox>", 91 extraSandbox: "allow-same-origin" 92 }); 93 ok(true, "did not crash"); 94 ifr.remove(); 95 } 96 97 async function test_sandboxed_iframe_opens_window() { 98 // <iframe sandboxed> does window.open() which inherits the same principal 99 const { ifr } = await createSandboxedIframe({ extraSandbox: "allow-popups" }); 100 101 await SpecialPowers.spawn(ifr, [], () => { 102 const origin = content.document.nodePrincipal.siteOrigin; 103 104 const popup = content.open(); 105 is(popup.document.readyState, "complete", "Popup from sandbox loaded synchronously"); 106 const popupOrigin = SpecialPowers.wrap(popup.document).nodePrincipal.siteOrigin; 107 ok(popupOrigin != origin, "Popup from sandboxed iframe is isolated from it."); 108 109 popup.close(); 110 }); 111 112 ifr.remove(); 113 } 114 115 // Running 116 117 async function tests() { 118 SimpleTest.waitForExplicitFinish(); 119 120 121 await Promise.all([ 122 test_sandboxed_iframe(), 123 test_nested_iframes(), 124 test_nested_iframes_crash(), 125 test_sandboxed_iframe_opens_window(), 126 ]); 127 128 SimpleTest.finish(); 129 } 130 131 tests(); 132 </script> 133 </html>