summaryrefslogtreecommitdiffstats
path: root/dom/security/test/referrer-policy/referrer_testserver.sjs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/security/test/referrer-policy/referrer_testserver.sjs465
1 files changed, 465 insertions, 0 deletions
diff --git a/dom/security/test/referrer-policy/referrer_testserver.sjs b/dom/security/test/referrer-policy/referrer_testserver.sjs
new file mode 100644
index 0000000000..198780a27f
--- /dev/null
+++ b/dom/security/test/referrer-policy/referrer_testserver.sjs
@@ -0,0 +1,465 @@
+/*
+* 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
+*/
+
+Components.utils.importGlobalProperties(["URLSearchParams"]);
+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 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}'>`;
+}
+
+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);
+ return;
+}