| <!DOCTYPE html> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| |
| <meta http-equiv="Content-Security-Policy" content="img-src 'none'"> |
| |
| <script> |
| let message_from = (w, starts_with) => { |
| return new Promise(resolve => { |
| window.addEventListener('message', msg => { |
| if (msg.source == w) { |
| if (!starts_with || msg.data.startsWith(starts_with)) |
| resolve(msg.data); |
| } |
| }); |
| }); |
| }; |
| |
| const img_url = window.origin + "/content-security-policy/support/fail.png"; |
| |
| const function_addImage_string = ` |
| function addImage() { |
| let img = document.createElement('img'); |
| img.src = '${img_url}'; |
| img.onload = () => opener.postMessage('img loaded', '*'); |
| img.onerror = () => opener.postMessage('img blocked', '*'); |
| document.body.appendChild(img); |
| } |
| `; |
| |
| const img_tag_string = ` |
| <img src="${img_url}" |
| onload="opener.postMessage('img loaded', '*');" |
| onerror="opener.postMessage('img blocked', '*');" |
| > |
| `; |
| |
| let write_img_to_popup = (popup) => { |
| let div = popup.document.createElement('div'); |
| div.innerHTML = img_tag_string; |
| popup.document.body.appendChild(div); |
| }; |
| |
| // A beforeunload event listener disables bfcache (Firefox only). |
| // |
| // Note: Chrome enables bfcache only on HTTP/HTTPS documents, so a blob will |
| // never be put in the bfcache. Moreover with Chrome, bfcache needs a single |
| // top-level browsing context in the browsing context group. Since we are |
| // using window.open() below, the back-forward cache is not triggered. |
| const disable_bfcache = ` |
| window.addEventListener('beforeunload', function(event) { |
| eval('1+1'); |
| }); |
| `; |
| |
| const blob_payload = ` |
| <!doctype html> |
| <script>${function_addImage_string}</scr`+`ipt> |
| <body onpageshow="addImage();"></body> |
| `; |
| let blob_url = URL.createObjectURL( |
| new Blob([blob_payload], { type: 'text/html' })); |
| |
| const blob_payload_no_bfcache = ` |
| <!doctype html> |
| <script>${disable_bfcache}</scr`+`ipt> |
| <script>${function_addImage_string}</scr`+`ipt> |
| <body onpageshow="addImage();"></body> |
| `; |
| let blob_url_no_bfcache = URL.createObjectURL( |
| new Blob([blob_payload_no_bfcache], { type: 'text/html' })); |
| |
| let testCases = [ |
| { |
| url: "about:blank", |
| add_img_function: write_img_to_popup, |
| other_origin: window.origin, |
| name: '"about:blank" document is navigated back from history same-origin.', |
| }, |
| { |
| url: "about:blank", |
| add_img_function: write_img_to_popup, |
| other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}", |
| name: '"about:blank" document is navigated back from history cross-origin.', |
| }, |
| { |
| url: blob_url, |
| add_img_function: () => {}, |
| other_origin: window.origin, |
| name: 'blob URL document is navigated back from history same-origin.', |
| }, |
| { |
| url: blob_url, |
| add_img_function: () => {}, |
| other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}", |
| name: 'blob URL document is navigated back from history cross-origin.', |
| }, |
| { |
| url: blob_url_no_bfcache, |
| add_img_function: () => {}, |
| other_origin: window.origin, |
| name: 'blob URL document is navigated back from history (without bfcache on Firefox) same-origin.', |
| }, |
| { |
| url: blob_url_no_bfcache, |
| add_img_function: () => {}, |
| other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}", |
| name: 'blob URL document is navigated back from history (without bfcache on Firefox) cross-origin.', |
| }, |
| ]; |
| |
| let async_promise_test = (promise, description) => { |
| async_test(test => { |
| promise(test) |
| .then(() => {test.done();}) |
| .catch(test.step_func(error => { throw error; })); |
| }, description); |
| }; |
| |
| testCases.forEach(testCase => { |
| async_promise_test(async t => { |
| // Create a popup. |
| let popup = window.open(); |
| |
| // Closing fails sometimes on Firefox: |
| // https://bugzilla.mozilla.org/show_bug.cgi?id=1698093 |
| t.add_cleanup(() => { try { popup.close(); } catch {} }); |
| |
| // Perform a real navigation in the popup. This is needed because the |
| // initial empty document is not stored in history (so there is no way of |
| // navigating back to it and test history inheritance). |
| let loaded_1 = message_from(popup); |
| popup.location = testCase.other_origin + "/content-security-policy/inheritance/support/postmessage-opener.html"; |
| assert_equals(await loaded_1, "ready", |
| "Could not open and navigate popup."); |
| |
| // Navigate to the local scheme document. We need to wait for the |
| // navigation to succeed. |
| let wait = () => t.step_wait( |
| condition = () => { |
| try { |
| return popup.location.href == testCase.url; |
| } catch {} |
| return false; |
| }, |
| description = "Wait for the popup to navigate.", |
| timeout=3000, |
| interval=50); |
| |
| let message = message_from(popup); |
| popup.location = testCase.url; |
| await wait(); |
| |
| testCase.add_img_function(popup); |
| // Check that the local scheme document inherits CSP from the initiator. |
| assert_equals(await message, "img blocked", |
| "Image should be blocked by CSP inherited from navigation initiator."); |
| |
| let loaded_2 = message_from(popup, "ready"); |
| let message_2 = message_from(popup, "img"); |
| // Navigate to another page, which will navigate back. |
| popup.location = testCase.other_origin + "/content-security-policy/inheritance/support/message-opener-and-navigate-back.html"; |
| assert_equals(await loaded_2, "ready", |
| "Could not navigate popup."); |
| |
| // We need to wait for the history navigation to be performed. |
| await wait(); |
| |
| // Check that the "about:blank" document reloaded from history has the |
| // original CSPs. |
| testCase.add_img_function(popup); |
| assert_equals(await message_2, "img blocked", |
| "Image should be blocked by CSP reloaded from history."); |
| }, "History navigation: " + testCase.name); |
| }); |
| </script> |