195 lines
7 KiB
HTML
195 lines
7 KiB
HTML
<!DOCTYPE html>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/common/utils.js"></script>
|
|
|
|
<meta http-equiv="Content-Security-Policy" content="img-src 'none'">
|
|
|
|
<script>
|
|
let message_from = (source_token, starts_with) => {
|
|
return new Promise(resolve => {
|
|
window.addEventListener('message', msg => {
|
|
if (msg.data.token === source_token) {
|
|
if (!starts_with || msg.data.msg.startsWith(starts_with))
|
|
resolve(msg.data.msg);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
const img_url = window.origin + "/content-security-policy/support/fail.png";
|
|
|
|
const function_addImage_string = img_token => `
|
|
function addImage() {
|
|
let img = document.createElement('img');
|
|
img.src = '${img_url}';
|
|
img.onload = () => opener.postMessage(
|
|
{msg: 'img loaded', token: '${img_token}'}, '*');
|
|
img.onerror = () => opener.postMessage(
|
|
{msg: 'img blocked', token: '${img_token}'}, '*');
|
|
document.body.appendChild(img);
|
|
}
|
|
`;
|
|
|
|
const img_tag_string = img_token => `
|
|
<img src="${img_url}"
|
|
onload="opener.postMessage(
|
|
{msg: 'img loaded', token: '${img_token}'}, '*');"
|
|
onerror="opener.postMessage(
|
|
{msg: 'img blocked', token: '${img_token}'}, '*');"
|
|
>
|
|
`;
|
|
|
|
let write_img_to_popup = (popup, img_token) => {
|
|
let div = popup.document.createElement('div');
|
|
div.innerHTML = img_tag_string(img_token);
|
|
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 = blob_token => `
|
|
<!doctype html>
|
|
<script>window.window_token = "${blob_token}";</scr`+`ipt>
|
|
<script>${function_addImage_string(`${blob_token}`)}</scr`+`ipt>
|
|
<body onpageshow="addImage();"></body>
|
|
`;
|
|
let blob_url = blob_token => URL.createObjectURL(
|
|
new Blob([blob_payload(blob_token)], { type: 'text/html' }));
|
|
|
|
const blob_payload_no_bfcache = blob_token => `
|
|
<!doctype html>
|
|
<script>window.window_token = "${blob_token}";</scr`+`ipt>
|
|
<script>${disable_bfcache}</scr`+`ipt>
|
|
<script>${function_addImage_string(`${blob_token}`)}</scr`+`ipt>
|
|
<body onpageshow="addImage();"></body>
|
|
`;
|
|
let blob_url_no_bfcache = blob_token => URL.createObjectURL(
|
|
new Blob([blob_payload_no_bfcache(blob_token)], { type: 'text/html' }));
|
|
|
|
let testCases = [
|
|
test_token => ({
|
|
token: test_token,
|
|
url: "about:blank",
|
|
add_img_function: popup => write_img_to_popup(popup, test_token),
|
|
other_origin: window.origin,
|
|
name: '"about:blank" document is navigated back from history same-origin.',
|
|
}),
|
|
test_token => ({
|
|
token: test_token,
|
|
url: "about:blank",
|
|
add_img_function: popup => write_img_to_popup(popup, test_token),
|
|
other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}",
|
|
name: '"about:blank" document is navigated back from history cross-origin.',
|
|
}),
|
|
test_token => ({
|
|
token: test_token,
|
|
url: blob_url(test_token),
|
|
other_origin: window.origin,
|
|
name: 'blob URL document is navigated back from history same-origin.',
|
|
}),
|
|
test_token => ({
|
|
token: test_token,
|
|
url: blob_url(test_token),
|
|
other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}",
|
|
name: 'blob URL document is navigated back from history cross-origin.',
|
|
}),
|
|
test_token => ({
|
|
token: test_token,
|
|
url: blob_url_no_bfcache(test_token),
|
|
other_origin: window.origin,
|
|
name: 'blob URL document is navigated back from history (without bfcache on Firefox) same-origin.',
|
|
}),
|
|
test_token => ({
|
|
token: test_token,
|
|
url: blob_url_no_bfcache(test_token),
|
|
other_origin: "http://{{hosts[alt][]}}:{{ports[http][0]}}",
|
|
name: 'blob URL document is navigated back from history (without bfcache on Firefox) cross-origin.',
|
|
}),
|
|
].map(f => f(token()));
|
|
|
|
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(() => { popup.close(); });
|
|
|
|
// 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).
|
|
const token_1 = token();
|
|
let loaded_1 = message_from(token_1);
|
|
popup.location = testCase.other_origin +
|
|
`/content-security-policy/inheritance/support` +
|
|
`/postmessage-opener.html?token=${token_1}`;
|
|
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(testCase.token);
|
|
popup.location = testCase.url;
|
|
await wait();
|
|
if (testCase.add_img_function) {
|
|
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.");
|
|
|
|
const token_2 = token();
|
|
let loaded_2 = message_from(token_2, "ready");
|
|
let message_2 = message_from(testCase.token, "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?token=${token_2}`;
|
|
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.
|
|
if (testCase.add_img_function) {
|
|
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>
|