require-corp.https.html (9572B)
1 <!doctype html> 2 <meta name="timeout" content="long"> 3 <title>Cross-Origin-Embedder-Policy header and nested navigable resource without such header</title> 4 <script src=/resources/testharness.js></script> 5 <script src=/resources/testharnessreport.js></script> 6 <script src="/common/get-host-info.sub.js"></script> 7 <script src="/common/utils.js"></script> <!-- Use token() to allow running tests in parallel --> 8 <div id=log></div> 9 <script> 10 const HOST = get_host_info(); 11 const BASE = new URL("resources", location).pathname; 12 13 async_test(t => { 14 const frame = document.createElement("iframe"); 15 t.add_cleanup(() => frame.remove()); 16 frame.src = "/common/blank.html"; 17 document.body.append(frame); 18 // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a 19 // timeout is used here. Long term all network error handling should be similar and have a 20 // reliable event. 21 assert_equals(frame.contentDocument.body.localName, "body"); 22 t.step_wait_func_done(() => frame.contentDocument === null); 23 }, `"require-corp" top-level: navigating a frame to "none" should fail`); 24 25 async_test(t => { 26 const frame = document.createElement("iframe"); 27 t.add_cleanup(() => frame.remove()); 28 const bc = new BroadcastChannel(token()); 29 bc.onmessage = t.step_func((event) => { 30 let payload = event.data; 31 assert_equals(payload, "loaded"); 32 t.step_wait_func_done(() => frame.contentDocument === null); 33 }); 34 frame.src = `resources/navigate-require-corp.sub.html?channelName=${bc.name}&to=/common/blank.html`; 35 document.body.append(frame); 36 assert_equals(frame.contentDocument.body.localName, "body"); 37 }, `"require-corp" top-level: navigating a frame from "require-corp" to "none" should fail`); 38 39 async_test(t => { 40 let pageLoaded = false; 41 const bc = new BroadcastChannel(token()); 42 let finished = false; 43 bc.onmessage = t.step_func((event) => { 44 let payload = event.data; 45 assert_equals(payload, "loaded"); 46 pageLoaded = true; 47 }); 48 49 const bc2 = new BroadcastChannel(token()); 50 bc2.onmessage = t.step_func_done((event) => { 51 let payload = event.data; 52 assert_equals(payload, "loaded"); 53 assert_equals(pageLoaded, true); 54 }); 55 56 const win = window.open(`resources/navigate-none.sub.html?channelName=${bc.name}&to=navigate-none.sub.html?channelName=${bc2.name}`, "_blank", "noopener"); 57 assert_equals(win, null); 58 }, `"require-corp" top-level: creating a noopener "none" popup should succeed`); 59 60 async_test(t => { 61 let pageLoaded = false; 62 const bc = new BroadcastChannel(token()); 63 bc.onmessage = t.step_func_done((event) => { 64 pageLoaded = true; 65 let payload = event.data; 66 assert_equals(payload, "loaded"); 67 }); 68 69 const win = window.open(`resources/navigate-none.sub.html?channelName=${bc.name}&to=/common/blank.html`, "_blank"); 70 t.add_cleanup(() => win.close()); 71 }, `"require-corp" top-level: creating a "none" popup should succeed.`); 72 73 [ 74 { 75 "name": "", 76 "title": "as popup" 77 }, 78 { 79 "name": "noopener", 80 "title": "as noopener popup" 81 }, 82 { 83 "name": "clear opener", 84 "title": "as popup with opener set to null" 85 } 86 ].forEach(({name, title}) => { 87 async_test(t => { 88 let pageLoaded = false; 89 const bc = new BroadcastChannel(token()); 90 bc.onmessage = t.step_func(event => { 91 pageLoaded = true; 92 const payload = event.data; 93 assert_equals(payload, "loaded"); 94 }); 95 96 const bc2 = new BroadcastChannel(token()); 97 bc2.onmessage = t.step_func_done(event => { 98 const payload = event.data; 99 assert_equals(payload, "loaded"); 100 assert_equals(pageLoaded, true); 101 }); 102 103 let clearOpener = ""; 104 if (name === "clear opener") { 105 clearOpener = "&clearOpener=true" 106 } 107 108 let noopener = undefined; 109 if (name === "noopener") { 110 noopener = "noopener" 111 } 112 113 const win = window.open(`resources/navigate-require-corp.sub.html?channelName=${bc.name}${clearOpener}&to=navigate-none.sub.html?channelName=${bc2.name}`, "_blank", noopener); 114 if (name === "noopener") { 115 assert_equals(win, null); 116 } else { 117 t.add_cleanup(() => win.close()); 118 } 119 }, `"require-corp" top-level (${title}): navigating to "none" should succeed`); 120 }); 121 122 promise_test(async t => { 123 const response = await fetch(get_host_info().HTTPS_REMOTE_ORIGIN+"/html/cross-origin-embedder-policy/resources/nothing-cross-origin-corp.js", {mode: "no-cors"}); 124 assert_equals(response.type, "opaque"); 125 }, `"require-corp" top-level: fetch() to CORP: cross-origin response should succeed`); 126 127 promise_test(t => { 128 return promise_rejects_js(t, TypeError, fetch(get_host_info().HTTPS_REMOTE_ORIGIN+"/common/blank.html", {mode: "no-cors"})); 129 }, `"require-corp" top-level: fetch() to response without CORP should fail`); 130 131 promise_test(t => { 132 const w = window.open(); 133 return promise_rejects_js(t, w.TypeError, w.fetch(get_host_info().HTTPS_REMOTE_ORIGIN+"/common/blank.html", {mode: "no-cors"})); 134 }, `"require-corp" top-level: fetch() to response without CORP through a WindowProxy should fail`); 135 136 async_test(t => { 137 let w = window.open(); 138 const frame = w.document.createElement("iframe"); 139 t.add_cleanup(() => { 140 w.close(); 141 frame.remove(); 142 }); 143 frame.src = "/common/blank.html"; 144 document.body.append(frame); 145 // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a 146 // timeout is used here. Long term all network error handling should be similar and have a 147 // reliable event. 148 assert_equals(frame.contentDocument.body.localName, "body"); 149 t.step_wait_func_done(() => frame.contentDocument === null); 150 }, `"require-corp" top-level: navigating an iframe to a page without CORP, through a WindowProxy, should fail`); 151 152 async_test(t => { 153 const frame = document.createElement("iframe"); 154 const id = token(); 155 t.add_cleanup(() => frame.remove()); 156 window.addEventListener('message', t.step_func((e) => { 157 if (e.data === id) { 158 // Loaded! 159 t.done(); 160 } 161 })); 162 // REMOTE_ORIGIN is cross-origin, same-site. 163 frame.src = `${HOST.HTTPS_REMOTE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`; 164 document.body.append(frame); 165 }, 'CORP: same-site is checked and allowed.'); 166 167 async_test(t => { 168 const frame = document.createElement("iframe"); 169 const id = token(); 170 t.add_cleanup(() => frame.remove()); 171 let loaded = false; 172 window.addEventListener('message', t.step_func((e) => { 173 if (e.data === id) { 174 loaded = true; 175 } 176 })); 177 t.step_timeout(() => { 178 // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a 179 // timeout is used here. Long term all network error handling should be similar and have a 180 // reliable event. 181 assert_false(loaded); 182 t.done(); 183 }, 2000); 184 185 // NOTESAMESITE_ORIGIN is cross-origin, cross-site. 186 frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`; 187 document.body.append(frame); 188 }, 'CORP: same-site is checked and blocked.'); 189 190 async_test(t => { 191 const frame = document.createElement("iframe"); 192 const bc = new BroadcastChannel(token()); 193 t.add_cleanup(() => frame.remove()); 194 bc.onmessage = t.step_func_done((event) => { 195 const payload = event.data; 196 assert_equals(payload, "loaded"); 197 }); 198 199 const dest = `${HOST.ORIGIN}${BASE}/navigate-require-corp.sub.html?channelName=${bc.name}`; 200 // REMOTE_ORIGIN is cross-origin, same-site. 201 frame.src = `${HOST.REMOTE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?to=${encodeURIComponent(dest)}`; 202 document.body.append(frame); 203 }, 'navigation CORP is checked with the parent frame, not the navigation source - to be allowed'); 204 205 async_test(t => { 206 const frame = document.createElement("iframe"); 207 const bc = new BroadcastChannel(token()); 208 t.add_cleanup(() => frame.remove()); 209 let loaded = false; 210 bc.onmessage = t.step_func((event) => { 211 loaded = true; 212 }); 213 t.step_timeout(() => { 214 // Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a 215 // timeout is used here. Long term all network error handling should be similar and have a 216 // reliable event. 217 assert_false(loaded); 218 t.done(); 219 }, 2000); 220 221 const dest = `${HOST.REMOTE_ORIGIN}${BASE}/navigate-require-corp.sub.html?channelName=${bc.name}`; 222 // REMOTE_ORIGIN is cross-origin, same-site. 223 frame.src = `${HOST.REMOTE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?to=${encodeURIComponent(dest)}`; 224 document.body.append(frame); 225 }, 'navigation CORP is checked with the parent frame, not the navigation source - to be blocked'); 226 227 async_test(t => { 228 const bc = new BroadcastChannel(token()); 229 let loaded = false; 230 bc.onmessage = t.step_func((event) => { 231 loaded = true; 232 }); 233 t.step_timeout(() => { 234 // Make sure the iframe didn't load. See 235 // https://github.com/whatwg/html/issues/125 for why a timeout is used 236 // here. Long term all network error handling should be similar and have a 237 // reliable event. 238 assert_false(loaded); 239 t.done(); 240 }, 2000); 241 242 const dest = `${HOST.ORIGIN}${BASE}/navigate-require-corp.sub.html?channelName=${bc.name}`; 243 const frame = document.createElement("iframe"); 244 t.add_cleanup(() => frame.remove()); 245 // |dest| is a same-origin URL and hence not blocked by CORP but reidirect.py 246 // is a cross-origin (actually cross-site) URL, so blocked by CORP. 247 frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}/common/redirect.py?location=${encodeURIComponent(dest)}`; 248 document.body.append(frame); 249 }, 'navigation CORP is checked for each redirect'); 250 251 </script>