691 lines
18 KiB
JavaScript
691 lines
18 KiB
JavaScript
/*
|
|
* Test server for iframe, anchor, and area referrer attributes.
|
|
* https://bugzilla.mozilla.org/show_bug.cgi?id=1175736
|
|
* Also server for further referrer tests such as redirecting tests
|
|
* bug 1174913, bug 1175736, bug 1184781
|
|
*/
|
|
|
|
const SJS = "referrer_testserver.sjs?";
|
|
const SJS_PATH = "/tests/dom/base/test/";
|
|
const BASE_ORIGIN = "example.com";
|
|
const BASE_URL = BASE_ORIGIN + SJS_PATH + SJS;
|
|
const SHARED_KEY = SJS;
|
|
const SAME_ORIGIN = "mochi.test:8888" + SJS_PATH + SJS;
|
|
const CROSS_ORIGIN_URL = "test1.example.com" + SJS_PATH + SJS;
|
|
|
|
const IMG_BYTES = atob(
|
|
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" +
|
|
"P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
|
|
);
|
|
|
|
function createTestUrl(
|
|
aPolicy,
|
|
aAction,
|
|
aName,
|
|
aType,
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
crossOrigin,
|
|
referrerPolicyHeader
|
|
) {
|
|
var schemeTo = aSchemeTo || "http";
|
|
var schemeFrom = aSchemeFrom || "http";
|
|
var rpHeader = referrerPolicyHeader || "";
|
|
var url = schemeTo + "://";
|
|
url += crossOrigin ? CROSS_ORIGIN_URL : BASE_URL;
|
|
url +=
|
|
"ACTION=" +
|
|
aAction +
|
|
"&" +
|
|
"policy=" +
|
|
aPolicy +
|
|
"&" +
|
|
"NAME=" +
|
|
aName +
|
|
"&" +
|
|
"type=" +
|
|
aType +
|
|
"&" +
|
|
"RP_HEADER=" +
|
|
rpHeader +
|
|
"&" +
|
|
"SCHEME_FROM=" +
|
|
schemeFrom;
|
|
return url;
|
|
}
|
|
|
|
// test page using iframe referrer attribute
|
|
// if aParams are set this creates a test where the iframe url is a redirect
|
|
function createIframeTestPageUsingRefferer(
|
|
aMetaPolicy,
|
|
aAttributePolicy,
|
|
aNewAttributePolicy,
|
|
aName,
|
|
aParams,
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
aChangingMethod
|
|
) {
|
|
var metaString = "";
|
|
if (aMetaPolicy) {
|
|
metaString = `<meta name="referrer" content="${aMetaPolicy}">`;
|
|
}
|
|
var changeString = "";
|
|
if (aChangingMethod === "setAttribute") {
|
|
changeString = `document.getElementById("myframe").setAttribute("referrerpolicy", "${aNewAttributePolicy}")`;
|
|
} else if (aChangingMethod === "property") {
|
|
changeString = `document.getElementById("myframe").referrerPolicy = "${aNewAttributePolicy}"`;
|
|
}
|
|
var iFrameString = `<iframe src="" id="myframe" ${
|
|
aAttributePolicy ? ` referrerpolicy="${aAttributePolicy}"` : ""
|
|
}>iframe</iframe>`;
|
|
var iframeUrl = "";
|
|
if (aParams) {
|
|
aParams.delete("ACTION");
|
|
aParams.append("ACTION", "redirectIframe");
|
|
iframeUrl = "http://" + CROSS_ORIGIN_URL + aParams.toString();
|
|
} else {
|
|
iframeUrl = createTestUrl(
|
|
aAttributePolicy,
|
|
"test",
|
|
aName,
|
|
"iframe",
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
);
|
|
}
|
|
|
|
return `<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
${metaString}
|
|
</head>
|
|
<body>
|
|
${iFrameString}
|
|
<script>
|
|
window.addEventListener("load", function() {
|
|
${changeString}
|
|
document.getElementById("myframe").onload = function(){
|
|
parent.postMessage("childLoadComplete", "http://mochi.test:8888");
|
|
};
|
|
document.getElementById("myframe").src = "${iframeUrl}";
|
|
}.bind(window), false);
|
|
</script>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
function buildAnchorString(
|
|
aMetaPolicy,
|
|
aReferrerPolicy,
|
|
aName,
|
|
aRelString,
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
) {
|
|
if (aReferrerPolicy) {
|
|
return `<a href="${createTestUrl(
|
|
aReferrerPolicy,
|
|
"test",
|
|
aName,
|
|
"link",
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
)}" referrerpolicy="${aReferrerPolicy}" id="link" ${aRelString}>${aReferrerPolicy}</a>`;
|
|
}
|
|
return `<a href="${createTestUrl(
|
|
aMetaPolicy,
|
|
"test",
|
|
aName,
|
|
"link",
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
)}" id="link" ${aRelString}>link</a>`;
|
|
}
|
|
|
|
function buildAreaString(
|
|
aMetaPolicy,
|
|
aReferrerPolicy,
|
|
aName,
|
|
aRelString,
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
) {
|
|
var result = `<img src="file_mozfiledataurl_img.jpg" alt="image" usemap="#imageMap">`;
|
|
result += `<map name="imageMap">`;
|
|
if (aReferrerPolicy) {
|
|
result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(
|
|
aReferrerPolicy,
|
|
"test",
|
|
aName,
|
|
"link",
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
)}" alt="theArea" referrerpolicy="${aReferrerPolicy}" id="link" ${aRelString}>`;
|
|
} else {
|
|
result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(
|
|
aMetaPolicy,
|
|
"test",
|
|
aName,
|
|
"link",
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
)}" alt="theArea" id="link" ${aRelString}>`;
|
|
}
|
|
result += `</map>`;
|
|
|
|
return result;
|
|
}
|
|
|
|
// test page using anchor or area referrer attribute
|
|
function createAETestPageUsingRefferer(
|
|
aMetaPolicy,
|
|
aAttributePolicy,
|
|
aNewAttributePolicy,
|
|
aName,
|
|
aRel,
|
|
aStringBuilder,
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
aChangingMethod
|
|
) {
|
|
var metaString = "";
|
|
if (aMetaPolicy) {
|
|
metaString = `<head><meta name="referrer" content="${aMetaPolicy}"></head>`;
|
|
}
|
|
var changeString = "";
|
|
if (aChangingMethod === "setAttribute") {
|
|
changeString = `document.getElementById("link").setAttribute("referrerpolicy", "${aNewAttributePolicy}")`;
|
|
} else if (aChangingMethod === "property") {
|
|
changeString = `document.getElementById("link").referrerPolicy = "${aNewAttributePolicy}"`;
|
|
}
|
|
var relString = "";
|
|
if (aRel) {
|
|
relString = `rel="noreferrer"`;
|
|
}
|
|
var elementString = aStringBuilder(
|
|
aMetaPolicy,
|
|
aAttributePolicy,
|
|
aName,
|
|
relString,
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
);
|
|
|
|
return `<!DOCTYPE HTML>
|
|
<html>
|
|
${metaString}
|
|
<body>
|
|
${elementString}
|
|
<script>
|
|
window.addEventListener("load", function() {
|
|
${changeString}
|
|
document.getElementById("link").click();
|
|
}.bind(window), false);
|
|
</script>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
// test page using anchor target=_blank rel=noopener
|
|
function createTargetBlankRefferer(
|
|
aMetaPolicy,
|
|
aName,
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
aRpHeader
|
|
) {
|
|
var metaString = "";
|
|
if (aMetaPolicy) {
|
|
metaString = `<head><meta name="referrer" content="${aMetaPolicy}"></head>`;
|
|
}
|
|
var elementString = `<a href="${createTestUrl(
|
|
aMetaPolicy,
|
|
"test",
|
|
aName,
|
|
"link",
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
aRpHeader
|
|
)}" target=_blank rel="noopener" id="link">link</a>`;
|
|
|
|
return `<!DOCTYPE HTML>
|
|
<html>
|
|
${metaString}
|
|
<body>
|
|
${elementString}
|
|
<script>
|
|
window.addEventListener("load", function() {
|
|
let link = document.getElementById("link");
|
|
SpecialPowers.wrap(window).parent.postMessage("childLoadReady", "*");
|
|
link.click();
|
|
}.bind(window), false);
|
|
</script>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
// creates test page with img that is a redirect
|
|
function createRedirectImgTestCase(aParams, aAttributePolicy) {
|
|
var metaString = "";
|
|
if (aParams.has("META_POLICY")) {
|
|
metaString = `<meta name="referrer" content="${aParams.get(
|
|
"META_POLICY"
|
|
)}">`;
|
|
}
|
|
aParams.delete("ACTION");
|
|
aParams.append("ACTION", "redirectImg");
|
|
var imgUrl = "http://" + CROSS_ORIGIN_URL + aParams.toString();
|
|
|
|
return `<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
${metaString}
|
|
<title>Test referrer policies on redirect (img)</title>
|
|
</head>
|
|
<body>
|
|
<img id="testImg" src="${imgUrl}" ${
|
|
aAttributePolicy ? ` referrerpolicy="${aAttributePolicy}"` : ""
|
|
}>
|
|
<script>
|
|
window.addEventListener("load", function() {
|
|
parent.postMessage("childLoadComplete", "http://mochi.test:8888");
|
|
}.bind(window), false);
|
|
</script>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
// test page using link referrer attribute
|
|
function createLinkPageUsingRefferer(
|
|
aMetaPolicy,
|
|
aAttributePolicy,
|
|
aNewAttributePolicy,
|
|
aName,
|
|
aRel,
|
|
aStringBuilder,
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
aTestType
|
|
) {
|
|
var metaString = "";
|
|
if (aMetaPolicy) {
|
|
metaString = `<meta name="referrer" content="${aMetaPolicy}">`;
|
|
}
|
|
|
|
var changeString = "";
|
|
var policy = aAttributePolicy ? aAttributePolicy : aMetaPolicy;
|
|
var elementString = aStringBuilder(
|
|
policy,
|
|
aName,
|
|
aRel,
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
aTestType
|
|
);
|
|
|
|
if (aTestType === "setAttribute") {
|
|
changeString = `var link = document.getElementById("test_link");
|
|
link.setAttribute("referrerpolicy", "${aNewAttributePolicy}");
|
|
link.href = "${createTestUrl(
|
|
policy,
|
|
"test",
|
|
aName,
|
|
"link_element_" + aRel,
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
)}";`;
|
|
} else if (aTestType === "property") {
|
|
changeString = `var link = document.getElementById("test_link");
|
|
link.referrerPolicy = "${aNewAttributePolicy}";
|
|
link.href = "${createTestUrl(
|
|
policy,
|
|
"test",
|
|
aName,
|
|
"link_element_" + aRel,
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
)}";`;
|
|
}
|
|
|
|
return `<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
${metaString}
|
|
</head>
|
|
<body>
|
|
${elementString}
|
|
<script>
|
|
${changeString}
|
|
</script>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
function createFetchUserControlRPTestCase(
|
|
aName,
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
crossOrigin
|
|
) {
|
|
var srcUrl = createTestUrl(
|
|
"",
|
|
"test",
|
|
aName,
|
|
"fetch",
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
crossOrigin
|
|
);
|
|
|
|
return `<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Test user control referrer policies</title>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
fetch("${srcUrl}", {referrerPolicy: ""}).then(function (response) {
|
|
window.parent.postMessage("childLoadComplete", "http://mochi.test:8888");
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
function buildLinkString(
|
|
aPolicy,
|
|
aName,
|
|
aRel,
|
|
aSchemeFrom,
|
|
aSchemeTo,
|
|
aTestType
|
|
) {
|
|
var href = "";
|
|
var onChildComplete = `window.parent.postMessage("childLoadComplete", "http://mochi.test:8888");`;
|
|
var policy = "";
|
|
var asString = "";
|
|
var relString = "";
|
|
|
|
if (aRel) {
|
|
relString = `rel="${aRel}"`;
|
|
}
|
|
|
|
if (aPolicy) {
|
|
policy = `referrerpolicy=${aPolicy}`;
|
|
}
|
|
|
|
if (aRel == "preload") {
|
|
asString = 'as="image"';
|
|
}
|
|
|
|
if (!aTestType) {
|
|
href = `href=${createTestUrl(
|
|
aPolicy,
|
|
"test",
|
|
aName,
|
|
"link_element_" + aRel,
|
|
aSchemeFrom,
|
|
aSchemeTo
|
|
)}`;
|
|
}
|
|
|
|
return `<link ${relString} ${href} ${policy} ${asString} id="test_link" onload='${onChildComplete}' onerror='${onChildComplete}'>`;
|
|
}
|
|
|
|
// eslint-disable-next-line complexity
|
|
function handleRequest(request, response) {
|
|
var params = new URLSearchParams(request.queryString);
|
|
var action = params.get("ACTION");
|
|
var schemeFrom = params.get("SCHEME_FROM") || "http";
|
|
var schemeTo = params.get("SCHEME_TO") || "http";
|
|
var crossOrigin = params.get("CROSS_ORIGIN") || false;
|
|
var referrerPolicyHeader = params.get("RP_HEADER") || "";
|
|
|
|
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
|
if (referrerPolicyHeader) {
|
|
response.setHeader("Referrer-Policy", referrerPolicyHeader, false);
|
|
}
|
|
|
|
if (action === "resetState") {
|
|
setSharedState(SHARED_KEY, "{}");
|
|
response.write("");
|
|
return;
|
|
}
|
|
if (action === "get-test-results") {
|
|
// ?action=get-result
|
|
response.setHeader("Cache-Control", "no-cache", false);
|
|
response.setHeader("Content-Type", "text/plain", false);
|
|
response.write(getSharedState(SHARED_KEY));
|
|
return;
|
|
}
|
|
if (action === "redirect") {
|
|
response.write(
|
|
'<script>parent.postMessage("childLoadComplete", "http://mochi.test:8888");</script>'
|
|
);
|
|
return;
|
|
}
|
|
if (action === "redirectImg") {
|
|
params.delete("ACTION");
|
|
params.append("ACTION", "test");
|
|
params.append("type", "img");
|
|
// 302 found, 301 Moved Permanently, 303 See Other, 307 Temporary Redirect
|
|
response.setStatusLine("1.1", 302, "found");
|
|
response.setHeader(
|
|
"Location",
|
|
"http://" + CROSS_ORIGIN_URL + params.toString(),
|
|
false
|
|
);
|
|
return;
|
|
}
|
|
if (action === "redirectIframe") {
|
|
params.delete("ACTION");
|
|
params.append("ACTION", "test");
|
|
params.append("type", "iframe");
|
|
// 302 found, 301 Moved Permanently, 303 See Other, 307 Temporary Redirect
|
|
response.setStatusLine("1.1", 302, "found");
|
|
response.setHeader(
|
|
"Location",
|
|
"http://" + CROSS_ORIGIN_URL + params.toString(),
|
|
false
|
|
);
|
|
return;
|
|
}
|
|
if (action === "test") {
|
|
// ?action=test&policy=origin&name=name
|
|
var policy = params.get("policy");
|
|
var name = params.get("NAME");
|
|
var type = params.get("type");
|
|
var result = getSharedState(SHARED_KEY);
|
|
|
|
result = result ? JSON.parse(result) : {};
|
|
|
|
var referrerLevel = "none";
|
|
var test = {};
|
|
if (request.hasHeader("Referer")) {
|
|
var referrer = request.getHeader("Referer");
|
|
if (referrer.indexOf("referrer_testserver") > 0) {
|
|
referrerLevel = "full";
|
|
} else if (referrer.indexOf(schemeFrom + "://example.com") == 0) {
|
|
referrerLevel = "origin";
|
|
} else {
|
|
// this is never supposed to happen
|
|
referrerLevel = "other-origin";
|
|
}
|
|
test.referrer = referrer;
|
|
} else {
|
|
test.referrer = "";
|
|
}
|
|
test.policy = referrerLevel;
|
|
test.expected = policy;
|
|
|
|
result[name] = test;
|
|
|
|
setSharedState(SHARED_KEY, JSON.stringify(result));
|
|
|
|
if (type === "img" || type == "link_element_preload") {
|
|
// return image
|
|
response.setHeader("Content-Type", "image/png");
|
|
response.write(IMG_BYTES);
|
|
return;
|
|
}
|
|
if (type === "iframe") {
|
|
// return iframe page
|
|
response.write("<html><body>I am the iframe</body></html>");
|
|
return;
|
|
}
|
|
if (type === "link") {
|
|
// forward link click to redirect URL to finish test
|
|
var loc = "http://" + BASE_URL + "ACTION=redirect";
|
|
response.setStatusLine("1.1", 302, "Found");
|
|
response.setHeader("Location", loc, false);
|
|
}
|
|
return;
|
|
}
|
|
|
|
response.setHeader("Cache-Control", "no-cache", false);
|
|
response.setHeader("Content-Type", "text/html; charset=utf-8", false);
|
|
|
|
// parse test arguments and start test
|
|
var attributePolicy = params.get("ATTRIBUTE_POLICY") || "";
|
|
var newAttributePolicy = params.get("NEW_ATTRIBUTE_POLICY") || "";
|
|
var metaPolicy = params.get("META_POLICY") || "";
|
|
var rel = params.get("REL") || "";
|
|
var name = params.get("NAME");
|
|
|
|
// anchor & area
|
|
var _getPage = createAETestPageUsingRefferer.bind(
|
|
null,
|
|
metaPolicy,
|
|
attributePolicy,
|
|
newAttributePolicy,
|
|
name,
|
|
rel
|
|
);
|
|
var _getAnchorPage = _getPage.bind(
|
|
null,
|
|
buildAnchorString,
|
|
schemeFrom,
|
|
schemeTo
|
|
);
|
|
var _getAreaPage = _getPage.bind(null, buildAreaString, schemeFrom, schemeTo);
|
|
|
|
// aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aChangingMethod, aStringBuilder
|
|
if (action === "generate-anchor-policy-test") {
|
|
response.write(_getAnchorPage());
|
|
return;
|
|
}
|
|
if (action === "generate-anchor-changing-policy-test-set-attribute") {
|
|
response.write(_getAnchorPage("setAttribute"));
|
|
return;
|
|
}
|
|
if (action === "generate-anchor-changing-policy-test-property") {
|
|
response.write(_getAnchorPage("property"));
|
|
return;
|
|
}
|
|
if (action === "generate-area-policy-test") {
|
|
response.write(_getAreaPage());
|
|
return;
|
|
}
|
|
if (action === "generate-area-changing-policy-test-set-attribute") {
|
|
response.write(_getAreaPage("setAttribute"));
|
|
return;
|
|
}
|
|
if (action === "generate-area-changing-policy-test-property") {
|
|
response.write(_getAreaPage("property"));
|
|
return;
|
|
}
|
|
if (action === "generate-anchor-target-blank-policy-test") {
|
|
response.write(
|
|
createTargetBlankRefferer(
|
|
metaPolicy,
|
|
name,
|
|
schemeFrom,
|
|
schemeTo,
|
|
referrerPolicyHeader
|
|
)
|
|
);
|
|
return;
|
|
}
|
|
|
|
// iframe
|
|
_getPage = createIframeTestPageUsingRefferer.bind(
|
|
null,
|
|
metaPolicy,
|
|
attributePolicy,
|
|
newAttributePolicy,
|
|
name,
|
|
"",
|
|
schemeFrom,
|
|
schemeTo
|
|
);
|
|
|
|
// aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aChangingMethod
|
|
if (action === "generate-iframe-policy-test") {
|
|
response.write(_getPage());
|
|
return;
|
|
}
|
|
if (action === "generate-iframe-changing-policy-test-set-attribute") {
|
|
response.write(_getPage("setAttribute"));
|
|
return;
|
|
}
|
|
if (action === "generate-iframe-changing-policy-test-property") {
|
|
response.write(_getPage("property"));
|
|
return;
|
|
}
|
|
|
|
// redirect tests with img and iframe
|
|
if (action === "generate-img-redirect-policy-test") {
|
|
response.write(createRedirectImgTestCase(params, attributePolicy));
|
|
return;
|
|
}
|
|
if (action === "generate-iframe-redirect-policy-test") {
|
|
response.write(
|
|
createIframeTestPageUsingRefferer(
|
|
metaPolicy,
|
|
attributePolicy,
|
|
newAttributePolicy,
|
|
name,
|
|
params,
|
|
schemeFrom,
|
|
schemeTo
|
|
)
|
|
);
|
|
return;
|
|
}
|
|
|
|
var _getPage = createLinkPageUsingRefferer.bind(
|
|
null,
|
|
metaPolicy,
|
|
attributePolicy,
|
|
newAttributePolicy,
|
|
name,
|
|
rel
|
|
);
|
|
var _getLinkPage = _getPage.bind(null, buildLinkString, schemeFrom, schemeTo);
|
|
|
|
// link
|
|
if (action === "generate-link-policy-test") {
|
|
response.write(_getLinkPage());
|
|
return;
|
|
}
|
|
if (action === "generate-link-policy-test-set-attribute") {
|
|
response.write(_getLinkPage("setAttribute"));
|
|
return;
|
|
}
|
|
if (action === "generate-link-policy-test-property") {
|
|
response.write(_getLinkPage("property"));
|
|
return;
|
|
}
|
|
|
|
if (action === "generate-fetch-user-control-policy-test") {
|
|
response.write(
|
|
createFetchUserControlRPTestCase(name, schemeFrom, schemeTo, crossOrigin)
|
|
);
|
|
return;
|
|
}
|
|
|
|
response.write("I don't know action " + action);
|
|
}
|