173 lines
6.6 KiB
HTML
173 lines
6.6 KiB
HTML
<!DOCTYPE html>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
|
|
<meta http-equiv="Content-Security-Policy" content="img-src http://{{hosts[][www]}}:{{ports[http][0]}}">
|
|
<body>
|
|
<script>
|
|
let message_from = w => {
|
|
return new Promise(resolve => {
|
|
window.addEventListener('message', msg => {
|
|
if (msg.source == w) {
|
|
resolve(msg.data);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
// `iframe_a` and `iframe_b` are two helper iframes with different
|
|
// CSPs.
|
|
let iframe_a, iframe_b;
|
|
|
|
// Setup `iframe_a` and `iframe_b`.
|
|
promise_setup(async () => {
|
|
iframe_a = document.createElement('iframe');
|
|
iframe_a.src = "./support/iframe-do.sub.html?" +
|
|
"img-src=http://{{hosts[][www1]}}:{{ports[http][0]}}";
|
|
document.body.appendChild(iframe_a);
|
|
await message_from(iframe_a.contentWindow);
|
|
|
|
iframe_b = document.createElement('iframe');
|
|
iframe_b.id = 'iframe_b';
|
|
iframe_b.src = "./support/iframe-do.sub.html?" +
|
|
"img-src=http://{{hosts[][www2]}}:{{ports[http][0]}}";
|
|
document.body.appendChild(iframe_b);
|
|
await message_from(iframe_b.contentWindow);
|
|
});
|
|
|
|
let test_iframe_id_counter = 0;
|
|
|
|
// Helper function to create the target iframe of a navigation.
|
|
let create_test_iframe = async () => {
|
|
let test_iframe = document.createElement('iframe');
|
|
test_iframe.id = "test_iframe_" + test_iframe_id_counter++;
|
|
test_iframe.name = test_iframe.id;
|
|
document.body.appendChild(test_iframe);
|
|
return test_iframe;
|
|
}
|
|
|
|
// The following code will try loading several images and check
|
|
// whether CSP has been inherited by the parent ("p"), `iframe_a`
|
|
// ("a") or `iframe_b` ("b"). It will post a message to the top
|
|
// with the result.
|
|
let data_payload = `
|
|
<body><script>
|
|
new Promise(async (resolve, reject) => {
|
|
const img_path = "/content-security-policy/support/pass.png";
|
|
|
|
let img_loaded = (origin) => new Promise(resolve => {
|
|
let img = document.createElement('img');
|
|
img.onerror = () => resolve(false);
|
|
img.onload = () => resolve(true);
|
|
img.src = origin + img_path;
|
|
document.body.appendChild(img);
|
|
});
|
|
|
|
inherited_from_p = await img_loaded(
|
|
"http://{{hosts[][www]}}:{{ports[http][0]}}");
|
|
inherited_from_a = await img_loaded(
|
|
"http://{{hosts[][www1]}}:{{ports[http][0]}}");
|
|
inherited_from_b = await img_loaded(
|
|
"http://{{hosts[][www2]}}:{{ports[http][0]}}");
|
|
|
|
if (inherited_from_a + inherited_from_b +
|
|
inherited_from_p !== 1) {
|
|
reject("Exactly one CSP should be inherited");
|
|
}
|
|
if (inherited_from_a) resolve("a");
|
|
if (inherited_from_b) resolve("b");
|
|
if (inherited_from_p) resolve("p");
|
|
}).then(from => top.postMessage(from, '*'),
|
|
error => top.postMessage(error, '*'));
|
|
</scr`+`ipt></body>
|
|
`;
|
|
|
|
let data_url = "data:text/html;base64," + btoa(data_payload);
|
|
|
|
promise_test(async t => {
|
|
let test_iframe = await create_test_iframe();
|
|
iframe_a.contentWindow.postMessage(
|
|
`parent.document.getElementById('${test_iframe.id}').src = '${data_url}'`);
|
|
|
|
assert_equals(await message_from(test_iframe.contentWindow), "p");
|
|
}, "Setting src inherits from parent.");
|
|
|
|
promise_test(async t => {
|
|
let test_iframe = await create_test_iframe();
|
|
iframe_a.contentWindow.postMessage(
|
|
`parent.document.getElementById('${test_iframe.id}').contentWindow.location = '${data_url}'`);
|
|
|
|
assert_equals(await message_from(test_iframe.contentWindow), "a");
|
|
}, "Changing contentWindow.location inherits from who changed it.");
|
|
|
|
promise_test(async t => {
|
|
let test_iframe = await create_test_iframe();
|
|
window.navigate_test_iframe = () => {
|
|
test_iframe.contentWindow.location = data_url;
|
|
};
|
|
iframe_a.contentWindow.postMessage(`parent.navigate_test_iframe();`);
|
|
assert_equals(await message_from(test_iframe.contentWindow), "p");
|
|
}, "Changing contentWindow.location indirectly inherits from who changed it directly.");
|
|
|
|
promise_test(async t => {
|
|
let test_iframe = await create_test_iframe();
|
|
iframe_a.contentWindow.postMessage(
|
|
`window.open('${data_url}', "${test_iframe.name}")`);
|
|
|
|
assert_equals(await message_from(test_iframe.contentWindow), "a");
|
|
}, "window.open() inherits from caller.");
|
|
|
|
promise_test(async t => {
|
|
let test_iframe = await create_test_iframe();
|
|
let a = iframe_b.contentDocument.createElement('a');
|
|
a.id = 'a';
|
|
a.href = data_url;
|
|
a.target = test_iframe.name;
|
|
iframe_b.contentDocument.body.appendChild(a);
|
|
|
|
iframe_a.contentWindow.postMessage(
|
|
`parent.document.getElementById('iframe_b').contentDocument.getElementById('a').click();`);
|
|
|
|
assert_equals(await message_from(test_iframe.contentWindow), "b");
|
|
iframe_b.contentDocument.body.removeChild(a);
|
|
}, "Click on anchor inherits from owner of the anchor.");
|
|
|
|
promise_test(async t => {
|
|
let test_iframe = await create_test_iframe();
|
|
let form = iframe_b.contentDocument.createElement('form');
|
|
form.id = 'form';
|
|
form.action = data_url;
|
|
form.target = test_iframe.name;
|
|
form.method = "POST";
|
|
iframe_b.contentDocument.body.appendChild(form);
|
|
|
|
iframe_a.contentWindow.postMessage(
|
|
`parent.document.getElementById('iframe_b').contentDocument.getElementById('form').submit();`);
|
|
|
|
assert_equals(await message_from(test_iframe.contentWindow), "b");
|
|
iframe_b.contentDocument.body.removeChild(form);
|
|
}, "Form submission through submit() inherits from owner of form.");
|
|
|
|
promise_test(async t => {
|
|
let test_iframe = await create_test_iframe();
|
|
let form = iframe_b.contentDocument.createElement('form');
|
|
form.id = 'form';
|
|
form.action = data_url;
|
|
form.target = test_iframe.name;
|
|
form.method = "POST";
|
|
iframe_b.contentDocument.body.appendChild(form);
|
|
let button = iframe_b.contentDocument.createElement('button');
|
|
button.type = "submit";
|
|
button.value = "submit";
|
|
button.id = "button";
|
|
form.appendChild(button);
|
|
|
|
iframe_a.contentWindow.postMessage(
|
|
`parent.document.getElementById('iframe_b').contentDocument.getElementById('button').click();`);
|
|
|
|
assert_equals(await message_from(test_iframe.contentWindow), "b");
|
|
iframe_b.contentDocument.body.removeChild(form);
|
|
}, "Form submission through button click inherits from owner of form.");
|
|
|
|
</script>
|
|
</body>
|