Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

// META: script=/common/utils.js
// META: script=/common/get-host-info.sub.js
const origins = get_host_info();
promise_test(async function () {
const stash = token(),
redirectPath = "/fetch/origin/resources/redirect-and-stash.py";
// Cross-origin -> same-origin will result in setting the tainted origin flag for the second
// request.
let url = origins.HTTP_ORIGIN + redirectPath + "?stash=" + stash;
url = origins.HTTP_REMOTE_ORIGIN + redirectPath + "?stash=" + stash + "&location=" + encodeURIComponent(url) + "&dummyJS";
await fetch(url, { mode: "no-cors", method: "POST" });
const json = await (await fetch(redirectPath + "?dump&stash=" + stash)).json();
assert_equals(json[0], origins.HTTP_ORIGIN);
assert_equals(json[1], "null");
}, "Origin header and 308 redirect");
promise_test(async function () {
const stash = token(),
redirectPath = "/fetch/origin/resources/redirect-and-stash.py";
let url = origins.HTTP_ORIGIN + redirectPath + "?stash=" + stash;
url = origins.HTTP_REMOTE_ORIGIN + redirectPath + "?stash=" + stash + "&location=" + encodeURIComponent(url);
await new Promise(resolve => {
const frame = document.createElement("iframe");
frame.src = url;
frame.onload = () => {
resolve();
frame.remove();
}
document.body.appendChild(frame);
});
const json = await (await fetch(redirectPath + "?dump&stash=" + stash)).json();
assert_equals(json[0], "no Origin header");
assert_equals(json[1], "no Origin header");
}, "Origin header and GET navigation");
promise_test(async function () {
const stash = token(),
redirectPath = "/fetch/origin/resources/redirect-and-stash.py";
let url = origins.HTTP_ORIGIN + redirectPath + "?stash=" + stash;
url = origins.HTTP_REMOTE_ORIGIN + redirectPath + "?stash=" + stash + "&location=" + encodeURIComponent(url);
await new Promise(resolve => {
const frame = document.createElement("iframe");
self.addEventListener("message", e => {
if (e.data === "loaded") {
resolve();
frame.remove();
}
}, { once: true });
frame.onload = () => {
const doc = frame.contentDocument,
form = doc.body.appendChild(doc.createElement("form")),
submit = form.appendChild(doc.createElement("input"));
form.action = url;
form.method = "POST";
submit.type = "submit";
submit.click();
}
document.body.appendChild(frame);
});
const json = await (await fetch(redirectPath + "?dump&stash=" + stash)).json();
assert_equals(json[0], origins.HTTP_ORIGIN);
assert_equals(json[1], "null");
}, "Origin header and POST navigation");
function navigationReferrerPolicy(referrerPolicy, destination, expectedOrigin) {
return async function () {
const stash = token();
const referrerPolicyPath = "/fetch/origin/resources/referrer-policy.py";
const redirectPath = "/fetch/origin/resources/redirect-and-stash.py";
let postUrl =
(destination === "same-origin" ? origins.HTTP_ORIGIN
: origins.HTTP_REMOTE_ORIGIN) +
redirectPath + "?stash=" + stash;
await new Promise(resolve => {
const frame = document.createElement("iframe");
document.body.appendChild(frame);
frame.src = origins.HTTP_ORIGIN + referrerPolicyPath +
"?referrerPolicy=" + referrerPolicy;
self.addEventListener("message", function listener(e) {
if (e.data === "loaded") {
resolve();
frame.remove();
self.removeEventListener("message", listener);
} else if (e.data === "action") {
const doc = frame.contentDocument,
form = doc.body.appendChild(doc.createElement("form")),
submit = form.appendChild(doc.createElement("input"));
form.action = postUrl;
form.method = "POST";
submit.type = "submit";
submit.click();
}
});
});
const json = await (await fetch(redirectPath + "?dump&stash=" + stash)).json();
assert_equals(json[0], expectedOrigin);
};
}
function fetchReferrerPolicy(referrerPolicy, destination, fetchMode, expectedOrigin, httpMethod) {
return async function () {
const stash = token();
const redirectPath = "/fetch/origin/resources/redirect-and-stash.py";
let fetchUrl =
(destination === "same-origin" ? origins.HTTP_ORIGIN
: origins.HTTP_REMOTE_ORIGIN) +
redirectPath + "?stash=" + stash + "&dummyJS";
await fetch(fetchUrl, { mode: fetchMode, method: httpMethod , "referrerPolicy": referrerPolicy});
const json = await (await fetch(redirectPath + "?dump&stash=" + stash)).json();
assert_equals(json[0], expectedOrigin);
};
}
function referrerPolicyTestString(referrerPolicy, method, destination) {
return "Origin header and " + method + " " + destination + " with Referrer-Policy " +
referrerPolicy;
}
[
{
"policy": "no-referrer",
"expectedOriginForSameOrigin": "null",
"expectedOriginForCrossOrigin": "null"
},
{
"policy": "same-origin",
"expectedOriginForSameOrigin": origins.HTTP_ORIGIN,
"expectedOriginForCrossOrigin": "null"
},
{
"policy": "origin-when-cross-origin",
"expectedOriginForSameOrigin": origins.HTTP_ORIGIN,
"expectedOriginForCrossOrigin": origins.HTTP_ORIGIN
},
{
"policy": "no-referrer-when-downgrade",
"expectedOriginForSameOrigin": origins.HTTP_ORIGIN,
"expectedOriginForCrossOrigin": origins.HTTP_ORIGIN
},
{
"policy": "unsafe-url",
"expectedOriginForSameOrigin": origins.HTTP_ORIGIN,
"expectedOriginForCrossOrigin": origins.HTTP_ORIGIN
},
].forEach(testObj => {
[
{
"name": "same-origin",
"expectedOrigin": testObj.expectedOriginForSameOrigin
},
{
"name": "cross-origin",
"expectedOrigin": testObj.expectedOriginForCrossOrigin
}
].forEach(destination => {
// Test form POST navigation
promise_test(navigationReferrerPolicy(testObj.policy,
destination.name,
destination.expectedOrigin),
referrerPolicyTestString(testObj.policy, "POST",
destination.name + " navigation"));
// Test fetch
promise_test(fetchReferrerPolicy(testObj.policy,
destination.name,
"no-cors",
destination.expectedOrigin,
"POST"),
referrerPolicyTestString(testObj.policy, "POST",
destination.name + " fetch no-cors mode"));
// Test cors mode POST
promise_test(fetchReferrerPolicy(testObj.policy,
destination.name,
"cors",
origins.HTTP_ORIGIN,
"POST"),
referrerPolicyTestString(testObj.policy, "POST",
destination.name + " fetch cors mode"));
// Test cors mode GET
promise_test(fetchReferrerPolicy(testObj.policy,
destination.name,
"cors",
(destination.name == "same-origin") ? "no Origin header" : origins.HTTP_ORIGIN,
"GET"),
referrerPolicyTestString(testObj.policy, "GET",
destination.name + " fetch cors mode"));
});
});