cross-partition-navigation.https.html (10210B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <meta name="timeout" content="long"> 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> 8 <script src="/common/dispatcher/dispatcher.js"></script> 9 <!-- Pull in executor_path needed by newPopup / newIframe --> 10 <script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"></script> 11 <!-- Pull in importScript / newPopup / newIframe --> 12 <script src="/html/anonymous-iframe/resources/common.js"></script> 13 <script src="resources/common.js"></script> 14 <body> 15 <script> 16 17 const navigation_handle_null = "Navigation handle returns null"; 18 const navigation_handle_not_null = "Navigation handle returns not null"; 19 const opener_null_response = "Window.opener is null"; 20 const opener_not_null_response = "Window.opener isn't null"; 21 22 const does_blob_url_open_return_handle = (blob_url, response_queue_name) => ` 23 async function test() { 24 const handle = window.open("${blob_url}") 25 if (!handle) { 26 return send("${response_queue_name}", "${navigation_handle_null}"); 27 } 28 29 return send("${response_queue_name}", "${navigation_handle_not_null}"); 30 } 31 await test(); 32 `; 33 34 const opener_check_frame_html = (noopener_response_queue) => ` 35 <!doctype html> 36 <!-- dispatcher.js requires the baseURI to be set in order to compute 37 the server path correctly in the blob URL page. --> 38 <base href="${window.location.href}"> 39 <script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"><\/script> 40 <script src="/html/anonymous-iframe/resources/common.js"><\/script> 41 <script src="/common/utils.js"><\/script> 42 <script src="/common/dispatcher/dispatcher.js"><\/script> 43 <script> 44 if (window.opener === null) { 45 send("${noopener_response_queue}", "${opener_null_response}") 46 } else { 47 send("${noopener_response_queue}", "${opener_not_null_response}") 48 } 49 <\/script> 50 `; 51 52 // Tests blob URL window.open for same and cross partition iframes. 53 promise_test(t => { 54 return new Promise(async (resolve, reject) => { 55 try { 56 // Creates same and cross partition iframes. 57 const response_queue_uuid = token(); 58 const noopener_response_queue = token(); 59 60 const [cross_site_iframe_uuid, same_site_iframe_uuid] = 61 await create_test_iframes(t, response_queue_uuid); 62 63 const blob = new Blob([opener_check_frame_html(noopener_response_queue)], {type : "text/html"}); 64 const blob_url = URL.createObjectURL(blob); 65 66 // Attempt to open blob URL in cross partition iframe. 67 await send(cross_site_iframe_uuid, does_blob_url_open_return_handle(blob_url, response_queue_uuid)); 68 const response_1 = await receive(response_queue_uuid); 69 if (response_1 !== navigation_handle_null) { 70 reject(`Blob URL handle wasn't null in not-same-top-level-site iframe: ${response_1}`); 71 } 72 const noopener_response_1 = await receive(noopener_response_queue); 73 if (noopener_response_1 !== opener_null_response) { 74 reject(`Blob URL page opener wasn't null in not-same-top-level-site iframe.`); 75 } 76 77 // Attempt to open blob URL in same partition iframe. 78 await send(same_site_iframe_uuid, does_blob_url_open_return_handle(blob_url, response_queue_uuid)); 79 const response_2 = await receive(response_queue_uuid); 80 if (response_2 !== navigation_handle_not_null) { 81 reject(`Blob URL wasn't opened in same-top-level-site iframe: ${response_2}`); 82 } 83 const noopener_response_2 = await receive(noopener_response_queue); 84 if (noopener_response_2 !== opener_not_null_response) { 85 reject(`Blob URL page opener was null in same-top-level-site iframe`); 86 } 87 resolve(); 88 } catch (e) { 89 reject(e); 90 } 91 }); 92 }, "Blob URL window.open should enforce noopener for a cross-top-level-site navigation"); 93 94 const blob_url_iframe_html = (response_queue_uuid, message) => ` 95 <!doctype html> 96 <!-- dispatcher.js requires the baseURI to be set in order to compute 97 the server path correctly in the blob URL page. --> 98 <base href="${window.location.href}"> 99 <script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"><\/script> 100 <script src="/html/anonymous-iframe/resources/common.js"><\/script> 101 <script src="/common/utils.js"><\/script> 102 <script src="/common/dispatcher/dispatcher.js"><\/script> 103 <script> 104 send("${response_queue_uuid}", "${message}"); 105 <\/script> 106 `; 107 108 const create_iframe_with_blob_url = (blob_url, response_queue_uuid) => ` 109 const iframe = document.createElement('iframe'); 110 iframe.src = "${blob_url}"; 111 iframe.onload = () => { 112 const same_site_message = "same_partition_loaded"; 113 const blob_url_iframe_html = ${blob_url_iframe_html}; 114 const same_top_level_site_blob = new Blob([blob_url_iframe_html("${response_queue_uuid}", same_site_message)], {type : "text/html"}); 115 const same_top_level_site_blob_url = URL.createObjectURL(same_top_level_site_blob); 116 const iframe2 = document.createElement('iframe'); 117 iframe2.src = same_top_level_site_blob_url; 118 document.body.appendChild(iframe2); 119 }; 120 document.body.appendChild(iframe); 121 `; 122 123 // Tests blob URL subframe navigations for same and cross partition iframes. 124 promise_test(t => { 125 return new Promise(async (resolve, reject) => { 126 try { 127 // Creates same and cross partition iframes. 128 const response_queue_uuid = token(); 129 const cross_site_message = "cross_partition_loaded"; 130 131 const [cross_site_iframe_uuid, same_site_iframe_uuid] = 132 await create_test_iframes(t, response_queue_uuid); 133 134 // Create blob URL for the cross-site test. 135 const cross_site_blob = new Blob([blob_url_iframe_html(response_queue_uuid, cross_site_message)], {type: "text/html"}); 136 const cross_site_blob_url = URL.createObjectURL(cross_site_blob); 137 138 // Attempt to open blob URL in cross partition iframe. 139 await send(cross_site_iframe_uuid, create_iframe_with_blob_url(cross_site_blob_url, response_queue_uuid)); 140 141 const response = await receive(response_queue_uuid); 142 if (response === cross_site_message) { 143 reject(`Blob URL subframe navigation succeeded in not-same-top-level-site iframe.`); 144 } 145 resolve(); 146 } catch (e) { 147 reject(e); 148 } 149 }); 150 }, "Blob URL should partition subframe navigation."); 151 152 const open_blob_url_window_via_a_click = (blob_url) => ` 153 const link = document.createElement("a"); 154 link.href = "${blob_url}"; 155 link.target = "_blank"; 156 link.rel = "opener"; 157 document.body.appendChild(link); 158 link.click(); 159 `; 160 161 // Tests blob URL `<a target="_blank" rel="opener">` click for same and cross partition iframes. 162 promise_test(t => { 163 return new Promise(async (resolve, reject) => { 164 try { 165 // Creates same and cross partition iframes. 166 const noopener_response_queue = token(); 167 168 const [cross_site_iframe_uuid, same_site_iframe_uuid] = await create_test_iframes(t, token()); 169 170 const blob = new Blob([opener_check_frame_html(noopener_response_queue)], {type : "text/html"}); 171 const blob_url = URL.createObjectURL(blob); 172 173 // Attempt to click blob URL in cross partition iframe. 174 await send(cross_site_iframe_uuid, open_blob_url_window_via_a_click(blob_url)); 175 const noopener_response_1 = await receive(noopener_response_queue); 176 if (noopener_response_1 !== opener_null_response) { 177 reject(`Blob URL page opener wasn't null in not-same-top-level-site iframe.`); 178 } 179 180 // Attempt to click blob URL in same partition iframe. 181 await send(same_site_iframe_uuid, open_blob_url_window_via_a_click(blob_url)); 182 const noopener_response_2 = await receive(noopener_response_queue); 183 if (noopener_response_2 !== opener_not_null_response) { 184 reject(`Blob URL page opener was null in same-top-level-site iframe`); 185 } 186 resolve(); 187 } catch (e) { 188 reject(e); 189 } 190 }); 191 }, "Blob URL link click should enforce noopener for a cross-top-level-site navigation"); 192 193 const open_blob_url_window_via_area_click = (blob_url) => ` 194 const canvas = document.createElement("canvas"); 195 canvas.height = 1; 196 canvas.width = 1; 197 const dataURL = canvas.toDataURL(); 198 199 const image = document.createElement("img"); 200 image.src = dataURL; 201 document.body.appendChild(image); 202 203 const map = document.createElement("map"); 204 map.name = "map"; 205 image.useMap = "#map"; 206 document.body.appendChild(map); 207 208 const area = document.createElement("area"); 209 area.shape = "rect"; 210 area.coords = "0,0,1,1"; 211 area.href = "${blob_url}"; 212 area.target = "_blank"; 213 area.rel = "opener"; 214 map.appendChild(area); 215 area.click(); 216 `; 217 218 // Tests blob URL `<area target="_blank" rel="opener">` click for same and cross partition iframes. 219 promise_test(t => { 220 return new Promise(async (resolve, reject) => { 221 try { 222 // Creates same and cross partition iframes. 223 const noopener_response_queue = token(); 224 225 const [cross_site_iframe_uuid, same_site_iframe_uuid] = await create_test_iframes(t, token()); 226 227 const blob = new Blob([opener_check_frame_html(noopener_response_queue)], {type : "text/html"}); 228 const blob_url = URL.createObjectURL(blob); 229 230 // Attempt to click blob URL in cross partition iframe. 231 await send(cross_site_iframe_uuid, open_blob_url_window_via_area_click(blob_url)); 232 const noopener_response_1 = await receive(noopener_response_queue); 233 if (noopener_response_1 !== opener_null_response) { 234 reject(`Blob URL page opener wasn't null in not-same-top-level-site iframe.`); 235 } 236 237 // Attempt to click blob URL in same partition iframe. 238 await send(same_site_iframe_uuid, open_blob_url_window_via_area_click(blob_url)); 239 const noopener_response_2 = await receive(noopener_response_queue); 240 if (noopener_response_2 !== opener_not_null_response) { 241 reject(`Blob URL page opener was null in same-top-level-site iframe`); 242 } 243 resolve(); 244 } catch (e) { 245 reject(e); 246 } 247 }); 248 }, "Blob URL area element click should enforce noopener for a cross-top-level-site navigation"); 249 250 </script> 251 </body>