history-iframe.sub.html (6545B)
1 <!DOCTYPE html> 2 <meta name="timeout" content="long"> 3 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="/common/utils.js"></script> 7 8 <meta http-equiv="Content-Security-Policy" content="img-src 'none'"> 9 <body> 10 <script> 11 let message_from = (source_token, starts_with) => { 12 return new Promise(resolve => { 13 window.addEventListener('message', msg => { 14 if (msg.data.token === source_token) { 15 if (!starts_with || msg.data.msg.startsWith(starts_with)) 16 resolve(msg.data.msg); 17 } 18 }); 19 }); 20 }; 21 22 const img_url = window.origin + "/content-security-policy/support/fail.png"; 23 24 const img_tag_string = img_token => ` 25 <img src="${img_url}" 26 onload="top.postMessage( 27 {msg: 'img loaded', token: '${img_token}'}, '*');" 28 onerror="top.postMessage( 29 {msg: 'img blocked', token: '${img_token}'}, '*');" 30 > 31 `; 32 33 const html_test_payload = img_token => ` 34 <!doctype html> 35 <script> 36 function add_image() { 37 let img = document.createElement('img'); 38 img.onload = () => top.postMessage( 39 {msg: 'img loaded', token: '${img_token}'}, '*'); 40 img.onerror = () => top.postMessage( 41 {msg: 'img blocked', token: '${img_token}'}, '*'); 42 img.src = '${img_url}'; 43 document.body.appendChild(img); 44 } 45 </scr`+`ipt> 46 <body onpageshow="add_image();"></body> 47 `; 48 let blob_url = blob_token => URL.createObjectURL( 49 new Blob([html_test_payload(blob_token)], { type: 'text/html' })); 50 51 let write_img_to_about_blank = async (t, iframe, img_token) => { 52 await t.step_wait( 53 condition = () => { 54 try { 55 return iframe.contentWindow.location.href == "about:blank"; 56 } catch {} 57 return false; 58 }, 59 description = "Wait for the iframe to navigate.", 60 timeout=6000, 61 interval=50); 62 63 let div = iframe.contentDocument.createElement('div'); 64 div.innerHTML = img_tag_string(img_token); 65 iframe.contentDocument.body.appendChild(div); 66 }; 67 68 let testCases = [ 69 test_token => ({ 70 token: test_token, 71 url: "about:blank", 72 add_img_function: (t, iframe) => 73 write_img_to_about_blank(t, iframe, test_token), 74 other_origin: window.origin, 75 name: '"about:blank" document is navigated back from history same-origin.', 76 }), 77 test_token => ({ 78 token: test_token, 79 url: "about:blank", 80 add_img_function: (t, iframe) => 81 write_img_to_about_blank(t, iframe, test_token), 82 other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}", 83 name: '"about:blank" document is navigated back from history cross-origin.', 84 }), 85 test_token => ({ 86 token: test_token, 87 url: blob_url(test_token), 88 other_origin: window.origin, 89 name: 'blob URL document is navigated back from history same-origin.', 90 }), 91 test_token => ({ 92 token: test_token, 93 url: blob_url(test_token), 94 other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}", 95 name: 'blob URL document is navigated back from history cross-origin.', 96 }), 97 test_token => ({ 98 token: test_token, 99 url: `data:text/html,${html_test_payload(test_token)}`, 100 other_origin: window.origin, 101 name: 'data URL document is navigated back from history same-origin.', 102 }), 103 test_token => ({ 104 token: test_token, 105 url: `data:text/html,${html_test_payload(test_token)}`, 106 other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}", 107 name: 'data URL document is navigated back from history cross-origin.', 108 }), 109 test_token => ({ 110 token: test_token, 111 srcdoc: `${html_test_payload(test_token)}`, 112 other_origin: window.origin, 113 name: 'srcdoc iframe is navigated back from history same-origin.', 114 }), 115 test_token => ({ 116 token: test_token, 117 srcdoc: `${html_test_payload(test_token)}`, 118 other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}", 119 name: 'srcdoc iframe is navigated back from history cross-origin.', 120 }), 121 ].map(f => f(token())); 122 123 testCases.forEach(testCase => { 124 promise_test(async t => { 125 // Create an iframe. 126 let iframe = document.createElement('iframe'); 127 document.body.appendChild(iframe); 128 129 // Perform a real navigation in the iframe. This is needed because the 130 // initial empty document is not stored in history (so there is no way of 131 // navigating back to it and test history inheritance). 132 const token_1 = token(); 133 let loaded_1 = message_from(token_1); 134 iframe.contentWindow.location = testCase.other_origin + 135 "/content-security-policy/inheritance/support" + 136 `/postmessage-top.html?token=${token_1}`; 137 assert_equals(await loaded_1, "ready", 138 "Could not navigate iframe."); 139 140 // Navigate to the local scheme document. 141 let message = message_from(testCase.token); 142 if (testCase.url) 143 iframe.contentWindow.location = testCase.url; 144 else 145 iframe.srcdoc = testCase.srcdoc; 146 147 // If the local scheme document is "about:blank", we need to write its 148 // content now. 149 if (testCase.add_img_function) { 150 testCase.add_img_function(t, iframe); 151 } 152 153 // Check that the local scheme document inherits CSP from the initiator. 154 assert_equals(await message, "img blocked", 155 "Image should be blocked by CSP inherited from navigation initiator."); 156 157 // Navigate to another page, which will navigate back. 158 const token_2 = token(); 159 let loaded_2 = message_from(token_2, "ready"); 160 let message_2 = message_from(testCase.token, "img"); 161 iframe.contentWindow.location = testCase.other_origin + 162 "/content-security-policy/inheritance/support" + 163 `/message-top-and-navigate-back.html?token=${token_2}`; 164 assert_equals(await loaded_2, "ready", 165 "Could not navigate iframe."); 166 167 // If the local scheme document is "about:blank", we need to write its 168 // content again. 169 if (testCase.add_img_function) { 170 testCase.add_img_function(t, iframe); 171 } 172 173 // Check that the local scheme document reloaded from history still has 174 // the original CSPs. 175 assert_equals(await message_2, "img blocked", 176 "Image should be blocked by CSP reloaded from history."); 177 }, "History navigation in iframe: " + testCase.name); 178 }); 179 </script> 180 </body>