inheritance-from-initiator.sub.html (6761B)
1 <!DOCTYPE html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 5 <meta http-equiv="Content-Security-Policy" content="img-src http://{{hosts[][www]}}:{{ports[http][0]}}"> 6 <body> 7 <script> 8 let message_from = w => { 9 return new Promise(resolve => { 10 window.addEventListener('message', msg => { 11 if (msg.source == w) { 12 resolve(msg.data); 13 } 14 }); 15 }); 16 }; 17 18 // `iframe_a` and `iframe_b` are two helper iframes with different 19 // CSPs. 20 let iframe_a, iframe_b; 21 22 // Setup `iframe_a` and `iframe_b`. 23 promise_setup(async () => { 24 iframe_a = document.createElement('iframe'); 25 iframe_a.src = "./support/iframe-do.sub.html?" + 26 "img-src=http://{{hosts[][www1]}}:{{ports[http][0]}}"; 27 document.body.appendChild(iframe_a); 28 await message_from(iframe_a.contentWindow); 29 30 iframe_b = document.createElement('iframe'); 31 iframe_b.id = 'iframe_b'; 32 iframe_b.src = "./support/iframe-do.sub.html?" + 33 "img-src=http://{{hosts[][www2]}}:{{ports[http][0]}}"; 34 document.body.appendChild(iframe_b); 35 await message_from(iframe_b.contentWindow); 36 }); 37 38 let test_iframe_id_counter = 0; 39 40 // Helper function to create the target iframe of a navigation. 41 let create_test_iframe = async () => { 42 let test_iframe = document.createElement('iframe'); 43 test_iframe.id = "test_iframe_" + test_iframe_id_counter++; 44 test_iframe.name = test_iframe.id; 45 document.body.appendChild(test_iframe); 46 return test_iframe; 47 } 48 49 // The following code will try loading several images and check 50 // whether CSP has been inherited by the parent ("p"), `iframe_a` 51 // ("a") or `iframe_b` ("b"). It will post a message to the top 52 // with the result. 53 let data_payload = ` 54 <body><script> 55 new Promise(async (resolve, reject) => { 56 const img_path = "/content-security-policy/support/pass.png"; 57 58 let img_loaded = (origin) => new Promise(resolve => { 59 let img = document.createElement('img'); 60 img.onerror = () => resolve(false); 61 img.onload = () => resolve(true); 62 img.src = origin + img_path; 63 document.body.appendChild(img); 64 }); 65 66 inherited_from_p = await img_loaded( 67 "http://{{hosts[][www]}}:{{ports[http][0]}}"); 68 inherited_from_a = await img_loaded( 69 "http://{{hosts[][www1]}}:{{ports[http][0]}}"); 70 inherited_from_b = await img_loaded( 71 "http://{{hosts[][www2]}}:{{ports[http][0]}}"); 72 73 if (inherited_from_a + inherited_from_b + 74 inherited_from_p !== 1) { 75 reject("Exactly one CSP should be inherited"); 76 } 77 if (inherited_from_a) resolve("a"); 78 if (inherited_from_b) resolve("b"); 79 if (inherited_from_p) resolve("p"); 80 }).then(from => top.postMessage(from, '*'), 81 error => top.postMessage(error, '*')); 82 </scr`+`ipt></body> 83 `; 84 85 let data_url = "data:text/html;base64," + btoa(data_payload); 86 87 promise_test(async t => { 88 let test_iframe = await create_test_iframe(); 89 iframe_a.contentWindow.postMessage( 90 `parent.document.getElementById('${test_iframe.id}').src = '${data_url}'`); 91 92 assert_equals(await message_from(test_iframe.contentWindow), "p"); 93 }, "Setting src inherits from parent."); 94 95 promise_test(async t => { 96 let test_iframe = await create_test_iframe(); 97 iframe_a.contentWindow.postMessage( 98 `parent.document.getElementById('${test_iframe.id}').contentWindow.location = '${data_url}'`); 99 100 assert_equals(await message_from(test_iframe.contentWindow), "a"); 101 }, "Changing contentWindow.location inherits from who changed it."); 102 103 promise_test(async t => { 104 let test_iframe = await create_test_iframe(); 105 window.navigate_test_iframe = () => { 106 test_iframe.contentWindow.location = data_url; 107 }; 108 iframe_a.contentWindow.postMessage(`parent.navigate_test_iframe();`); 109 assert_equals(await message_from(test_iframe.contentWindow), "p"); 110 }, "Changing contentWindow.location indirectly inherits from who changed it directly."); 111 112 promise_test(async t => { 113 let test_iframe = await create_test_iframe(); 114 iframe_a.contentWindow.postMessage( 115 `window.open('${data_url}', "${test_iframe.name}")`); 116 117 assert_equals(await message_from(test_iframe.contentWindow), "a"); 118 }, "window.open() inherits from caller."); 119 120 promise_test(async t => { 121 let test_iframe = await create_test_iframe(); 122 let a = iframe_b.contentDocument.createElement('a'); 123 a.id = 'a'; 124 a.href = data_url; 125 a.target = test_iframe.name; 126 iframe_b.contentDocument.body.appendChild(a); 127 128 iframe_a.contentWindow.postMessage( 129 `parent.document.getElementById('iframe_b').contentDocument.getElementById('a').click();`); 130 131 assert_equals(await message_from(test_iframe.contentWindow), "b"); 132 iframe_b.contentDocument.body.removeChild(a); 133 }, "Click on anchor inherits from owner of the anchor."); 134 135 promise_test(async t => { 136 let test_iframe = await create_test_iframe(); 137 let form = iframe_b.contentDocument.createElement('form'); 138 form.id = 'form'; 139 form.action = data_url; 140 form.target = test_iframe.name; 141 form.method = "POST"; 142 iframe_b.contentDocument.body.appendChild(form); 143 144 iframe_a.contentWindow.postMessage( 145 `parent.document.getElementById('iframe_b').contentDocument.getElementById('form').submit();`); 146 147 assert_equals(await message_from(test_iframe.contentWindow), "b"); 148 iframe_b.contentDocument.body.removeChild(form); 149 }, "Form submission through submit() inherits from owner of form."); 150 151 promise_test(async t => { 152 let test_iframe = await create_test_iframe(); 153 let form = iframe_b.contentDocument.createElement('form'); 154 form.id = 'form'; 155 form.action = data_url; 156 form.target = test_iframe.name; 157 form.method = "POST"; 158 iframe_b.contentDocument.body.appendChild(form); 159 let button = iframe_b.contentDocument.createElement('button'); 160 button.type = "submit"; 161 button.value = "submit"; 162 button.id = "button"; 163 form.appendChild(button); 164 165 iframe_a.contentWindow.postMessage( 166 `parent.document.getElementById('iframe_b').contentDocument.getElementById('button').click();`); 167 168 assert_equals(await message_from(test_iframe.contentWindow), "b"); 169 iframe_b.contentDocument.body.removeChild(form); 170 }, "Form submission through button click inherits from owner of form."); 171 172 </script> 173 </body>