Source code
Revision control
Copy as Markdown
Other Tools
/*
* Test server for iframe, anchor, and area referrer attributes.
* Also server for further referrer tests such as redirecting tests
*/
const SJS = "referrer_testserver.sjs?";
const SJS_PATH = "/tests/dom/security/test/referrer-policy/";
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 HSTS_URL = "includesubdomains.preloaded.test" + 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(){
};
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 createImgTestCase(aParams, aAttributePolicy, aRedirect) {
var metaString = "";
if (aParams.has("META_POLICY")) {
metaString = `<meta name="referrer" content="${aParams.get(
"META_POLICY"
)}">`;
}
aParams.delete("ACTION");
if (aRedirect) {
aParams.append("ACTION", "redirectImg");
} else {
aParams.append("ACTION", "test");
aParams.append("type", "img");
}
var imgUrl =
"http://" +
(aParams.get("HSTS") ? HSTS_URL : 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() {
}.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) {
});
</script>
</body>
</html>`;
}
function buildLinkString(
aPolicy,
aName,
aRel,
aSchemeFrom,
aSchemeTo,
aTestType
) {
var href = "";
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(
);
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
let policy = params.get("policy");
let name = params.get("NAME");
let type = params.get("type");
let 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(createImgTestCase(params, attributePolicy, true));
return;
}
if (action === "generate-iframe-redirect-policy-test") {
response.write(
createIframeTestPageUsingRefferer(
metaPolicy,
attributePolicy,
newAttributePolicy,
name,
params,
schemeFrom,
schemeTo
)
);
return;
}
if (action === "generate-img-policy-test") {
response.write(createImgTestCase(params, attributePolicy, false));
return;
}
_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);
}