disallowed-navigations.https.html (4430B)
1 <!DOCTYPE html> 2 <title>Fenced frame disallowed navigations</title> 3 <meta name="timeout" content="long"> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="/common/dispatcher/dispatcher.js"></script> 7 <script src="/common/get-host-info.sub.js"></script> 8 <script src="/common/utils.js"></script> 9 <script src="resources/utils.js"></script> 10 <script src="/fetch/local-network-access/resources/support.sub.js"></script> 11 12 <body> 13 14 <script> 15 // Baseline tests: 16 // - Embedder can navigate iframe to blob: URL 17 // - Embedder can navigate iframe to data: URL 18 // - Same-origin embedder can navigate iframe to javascript: URL 19 // - Embedder can navigate iframe to http: URL 20 // Fenced frame tests: 21 // - Embedder cannot navigate fenced frame to blob: URL 22 // - Embedder cannot navigate fenced frame to data: URL 23 // - Same-origin embedder cannot navigate fenced frame to 24 // javascript: URL 25 // - Embedder cannot navigate fenced frame to http: URL 26 27 // Fenced frames are always put in the public IP address space which is the 28 // least privileged. In case a navigation to a local data: URL or blob: URL 29 // resource is allowed, they would only be able to fetch things that are *also* 30 // in the public IP address space. So for the document described by these local 31 // URLs, we'll set them up to only communicate back to the outer page via 32 // resources obtained in the public address space. 33 const kPublicUtils = resolveUrl("resources/utils.js", Server.HTTPS_PUBLIC); 34 35 // These are just baseline tests asserting that this test's machinery to load 36 // blob:, data:, and javascript: URLs work properly in contexts where they are 37 // expected to. 38 promise_test(async () => { 39 const key = token(); 40 attachIFrame(`data:text/html, ${createLocalSource(key, kPublicUtils)}`); 41 const result = await nextValueFromServer(key); 42 assert_equals(result, "LOADED"); 43 }, "iframe data: URL"); 44 45 promise_test(async () => { 46 const key = token(); 47 const blobURL = URL.createObjectURL( 48 new Blob([`${createLocalSource(key, kPublicUtils)}`], 49 {type: 'text/html'})); 50 attachIFrame(blobURL); 51 const result = await nextValueFromServer(key); 52 assert_equals(result, "LOADED"); 53 }, "iframe blob: URL"); 54 55 promise_test(async () => { 56 const iframe = attachIFrameContext(); 57 iframe.src = "javascript:window.jsURLExecuted = true;" 58 await iframe.execute(async () => { 59 assert_equals(window.jsURLExecuted, true); 60 }); 61 }, "iframe javascript: URL"); 62 63 // The following tests ensure that an embedder cannot navigate a fenced frame 64 // to: 65 // - data: URLs 66 // - blob: URLs 67 // - javascript: URLs 68 // - http: URLs 69 function getTimeoutPromise(t) { 70 return new Promise(resolve => 71 t.step_timeout(() => resolve("NOT LOADED"), 2000)); 72 } 73 74 promise_test(async t => { 75 const key = token(); 76 attachFencedFrame(`data:text/html, ${createLocalSource(key, kPublicUtils)}`); 77 const loaded_promise = nextValueFromServer(key); 78 const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]); 79 assert_equals(result, "NOT LOADED"); 80 }, `fenced frame data: URL`); 81 82 promise_test(async t => { 83 const key = token(); 84 const blobURL = URL.createObjectURL( 85 new Blob([`${createLocalSource(key, kPublicUtils)}`], 86 {type: 'text/html'})); 87 attachFencedFrame(blobURL); 88 const loaded_promise = nextValueFromServer(key); 89 const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]); 90 assert_equals(result, "NOT LOADED"); 91 }, `fenced frame blob: URL`); 92 93 promise_test(async t => { 94 const fencedframe = attachFencedFrameContext(); 95 fencedframe.src = "javascript:window.jsURLExecuted = true;" 96 // Just in case the javascript URL executes asynchronously, let's wait for 97 // it. 98 await getTimeoutPromise(t); 99 await fencedframe.execute(async () => { 100 assert_equals(window.jsURLExecuted, undefined); 101 }); 102 }, `fenced frame javascript: URL`); 103 104 promise_test(async t => { 105 const key = token(); 106 let http_url = new URL("resources/embeddee.html", 107 get_host_info().HTTP_ORIGIN + location.pathname); 108 http_url = generateURL(http_url, [key]); 109 assert_equals(http_url.protocol, "http:"); 110 const fencedframe = attachFencedFrame(http_url); 111 const loaded_promise = nextValueFromServer(key); 112 const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]); 113 assert_equals(result, "NOT LOADED"); 114 }, `fenced frame http: URL`); 115 116 </script> 117 118 </body>