diff options
Diffstat (limited to 'dom/security/test/referrer-policy')
9 files changed, 1261 insertions, 0 deletions
diff --git a/dom/security/test/referrer-policy/img_referrer_testserver.sjs b/dom/security/test/referrer-policy/img_referrer_testserver.sjs new file mode 100644 index 0000000000..03f680b83d --- /dev/null +++ b/dom/security/test/referrer-policy/img_referrer_testserver.sjs @@ -0,0 +1,298 @@ +var BASE_URL = 'example.com/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs'; +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="); + +function createTestUrl(aPolicy, aAction, aName, aContent) { + var content = aContent || 'text'; + return 'http://' + BASE_URL + '?' + + 'action=' + aAction + '&' + + 'policy=' + aPolicy + '&' + + 'name=' + aName + '&' + + 'content=' + content; +} + +function createTestPage(aHead, aImgPolicy, aName) { + var _createTestUrl = createTestUrl.bind(null, aImgPolicy, 'test', aName); + + return '<!DOCTYPE HTML>\n\ + <html>'+ + aHead + + '<body>\n\ + <img src="' + _createTestUrl('img') + '" referrerpolicy="' + aImgPolicy + '" id="image"></img>\n\ + <script>' + + + // LOAD EVENT (of the test) + // fires when the img resource for the page is loaded + 'window.addEventListener("load", function() {\n\ + parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }.bind(window), false);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +// Creates the following test cases for the specified referrer +// policy combination: +// <img> with referrer +function createTest(aPolicy, aImgPolicy, aName) { + var headString = '<head>'; + if (aPolicy) { + headString += '<meta name="referrer" content="' + aPolicy + '">'; + } + + headString += '<script></script>'; + + return createTestPage(headString, aImgPolicy, aName); +} + +// testing regular load img with referrer policy +// speculative parser should not kick in here +function createTest2(aImgPolicy, name) { + return createTestPage('', aImgPolicy, name); +} + +function createTest3(aImgPolicy1, aImgPolicy2, aImgPolicy3, aName) { + return '<!DOCTYPE HTML>\n\ + <html>\n\ + <body>\n\ + <img src="' + createTestUrl(aImgPolicy1, 'test', aName + aImgPolicy1) + '" referrerpolicy="' + aImgPolicy1 + '" id="image"></img>\n\ + <img src="' + createTestUrl(aImgPolicy2, 'test', aName + aImgPolicy2) + '" referrerpolicy="' + aImgPolicy2 + '" id="image"></img>\n\ + <img src="' + createTestUrl(aImgPolicy3, 'test', aName + aImgPolicy3) + '" referrerpolicy="' + aImgPolicy3 + '" id="image"></img>\n\ + <script>\n\ + var _numLoads = 0;' + + + // LOAD EVENT (of the test) + // fires when the img resource for the page is loaded + 'window.addEventListener("load", function() {\n\ + parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }.bind(window), false);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createTestPage2(aHead, aPolicy, aName) { + return '<!DOCTYPE HTML>\n\ + <html>'+ + aHead + + '<body>\n\ + <img src="' + createTestUrl(aPolicy, "test", aName) + '" id="image"></img>\n\ + <script>' + + + // LOAD EVENT (of the test) + // fires when the img resource for the page is loaded + 'window.addEventListener("load", function() {\n\ + parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }.bind(window), false);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createTestPage3(aHead, aPolicy, aName) { + return '<!DOCTYPE HTML>\n\ + <html>'+ + aHead + + '<body>\n\ + <script>' + + 'var image = new Image();\n\ + image.src = "' + createTestUrl(aPolicy, "test", aName, "image") + '";\n\ + image.referrerPolicy = "' + aPolicy + '";\n\ + image.onload = function() {\n\ + window.parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }\n\ + document.body.appendChild(image);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createTestPage4(aHead, aPolicy, aName) { + return '<!DOCTYPE HTML>\n\ + <html>'+ + aHead + + '<body>\n\ + <script>' + + 'var image = new Image();\n\ + image.referrerPolicy = "' + aPolicy + '";\n\ + image.src = "' + createTestUrl(aPolicy, "test", aName, "image") + '";\n\ + image.onload = function() {\n\ + window.parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }\n\ + document.body.appendChild(image);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createSetAttributeTest1(aPolicy, aImgPolicy, aName) { + var headString = '<head>'; + headString += '<meta name="referrer" content="' + aPolicy + '">'; + headString += '<script></script>'; + + return createTestPage3(headString, aImgPolicy, aName); +} + +function createSetAttributeTest2(aPolicy, aImgPolicy, aName) { + var headString = '<head>'; + headString += '<meta name="referrer" content="' + aPolicy + '">'; + headString += '<script></script>'; + + return createTestPage4(headString, aImgPolicy, aName); +} + + +function createTest4(aPolicy, aName) { + var headString = '<head>'; + headString += '<meta name="referrer" content="' + aPolicy + '">'; + headString += '<script></script>'; + + return createTestPage2(headString, aPolicy, aName); +} + +function createTest5(aPolicy, aName) { + var headString = '<head>'; + headString += '<meta name="referrer" content="' + aPolicy + '">'; + + return createTestPage2(headString, aPolicy, aName); +} + +function handleRequest(request, response) { + var sharedKey = 'img_referrer_testserver.sjs'; + var params = request.queryString.split('&'); + var action = params[0].split('=')[1]; + + response.setHeader('Cache-Control', 'no-cache', false); + response.setHeader('Content-Type', 'text/html; charset=utf-8', false); + + if (action === 'resetState') { + var state = getSharedState(sharedKey); + state = {}; + setSharedState(sharedKey, JSON.stringify(state)); + response.write(""); + return; + } + if (action === 'test') { + // ?action=test&policy=origin&name=name&content=content + var policy = params[1].split('=')[1]; + var name = params[2].split('=')[1]; + var content = params[3].split('=')[1]; + var result = getSharedState(sharedKey); + + if (result === '') { + result = {}; + } else { + result = JSON.parse(result); + } + + if (!result["tests"]) { + result["tests"] = {}; + } + + var referrerLevel = "none"; + var test = {} + if (request.hasHeader('Referer')) { + let referrer = request.getHeader('Referer'); + if (referrer.indexOf("img_referrer_testserver") > 0) { + referrerLevel = "full"; + } else if (referrer == "http://mochi.test:8888/") { + referrerLevel = "origin"; + } + test.referrer = request.getHeader('Referer'); + } else { + test.referrer = ''; + } + test.policy = referrerLevel; + test.expected = policy; + + result["tests"][name] = test; + + setSharedState(sharedKey, JSON.stringify(result)); + + if (content === 'image') { + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + } + return; + } + if (action === 'get-test-results') { + // ?action=get-result + response.write(getSharedState(sharedKey)); + return; + } + if (action === 'generate-img-policy-test') { + // ?action=generate-img-policy-test&imgPolicy=b64-encoded-string&name=name&policy=b64-encoded-string + var imgPolicy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + var metaPolicy = ''; + if (params[3]) { + metaPolicy = params[3].split('=')[1]; + } + + response.write(createTest(metaPolicy, imgPolicy, name)); + return; + } + if (action === 'generate-img-policy-test2') { + // ?action=generate-img-policy-test2&imgPolicy=b64-encoded-string&name=name + var imgPolicy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + + response.write(createTest2(imgPolicy, name)); + return; + } + if (action === 'generate-img-policy-test3') { + // ?action=generate-img-policy-test3&imgPolicy1=b64-encoded-string&imgPolicy2=b64-encoded-string&imgPolicy3=b64-encoded-string&name=name + var imgPolicy1 = unescape(params[1].split('=')[1]); + var imgPolicy2 = unescape(params[2].split('=')[1]); + var imgPolicy3 = unescape(params[3].split('=')[1]); + var name = unescape(params[4].split('=')[1]); + + response.write(createTest3(imgPolicy1, imgPolicy2, imgPolicy3, name)); + return; + } + if (action === 'generate-img-policy-test4') { + // ?action=generate-img-policy-test4&imgPolicy=b64-encoded-string&name=name + var policy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + + response.write(createTest4(policy, name)); + return; + } + if (action === 'generate-img-policy-test5') { + // ?action=generate-img-policy-test5&policy=b64-encoded-string&name=name + var policy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + + response.write(createTest5(policy, name)); + return; + } + + if (action === 'generate-setAttribute-test1') { + // ?action=generate-setAttribute-test1&policy=b64-encoded-string&name=name + var imgPolicy = unescape(params[1].split('=')[1]); + var policy = unescape(params[2].split('=')[1]); + var name = unescape(params[3].split('=')[1]); + + response.write(createSetAttributeTest1(policy, imgPolicy, name)); + return; + } + + if (action === 'generate-setAttribute-test2') { + // ?action=generate-setAttribute-test2&policy=b64-encoded-string&name=name + var imgPolicy = unescape(params[1].split('=')[1]); + var policy = unescape(params[2].split('=')[1]); + var name = unescape(params[3].split('=')[1]); + + response.write(createSetAttributeTest2(policy, imgPolicy, name)); + return; + } + + response.write("I don't know action "+action); + return; +} diff --git a/dom/security/test/referrer-policy/mochitest.ini b/dom/security/test/referrer-policy/mochitest.ini new file mode 100644 index 0000000000..60fa4ef1fa --- /dev/null +++ b/dom/security/test/referrer-policy/mochitest.ini @@ -0,0 +1,16 @@ +[DEFAULT] +prefs = + plugin.load_flash_only=false +support-files = + img_referrer_testserver.sjs + referrer_header.sjs + referrer_header_current_document_iframe.html + referrer_helper.js + referrer_testserver.sjs + +[test_img_referrer.html] +[test_referrer_header_current_document.html] +skip-if = (verify && debug && (os == 'linux')) +[test_referrer_redirect.html] +skip-if = (verify && debug) +# Please keep alphabetical order. diff --git a/dom/security/test/referrer-policy/referrer_header.sjs b/dom/security/test/referrer-policy/referrer_header.sjs new file mode 100644 index 0000000000..021e6cac44 --- /dev/null +++ b/dom/security/test/referrer-policy/referrer_header.sjs @@ -0,0 +1,6 @@ + +function handleRequest(request, response) { + response.setHeader("Referrer-Policy", "same-origin"); + response.write('<!DOCTYPE HTML><html><body>Loaded</body><script>parent.postMessage(document.referrer, "*");</script></html>'); +} + diff --git a/dom/security/test/referrer-policy/referrer_header_current_document_iframe.html b/dom/security/test/referrer-policy/referrer_header_current_document_iframe.html new file mode 100644 index 0000000000..5996c8ba8a --- /dev/null +++ b/dom/security/test/referrer-policy/referrer_header_current_document_iframe.html @@ -0,0 +1,12 @@ +<!DOCTYPE HTML> +<html> +<head> + <script> + window.addEventListener("load", function() { + document.getElementById("link").click(); + }); + </script> +</head> +<body> + <a id="link" href="http://example.org/tests/dom/security/test/referrer-policy/referrer_header.sjs">Navigate</a> +</body> diff --git a/dom/security/test/referrer-policy/referrer_helper.js b/dom/security/test/referrer-policy/referrer_helper.js new file mode 100644 index 0000000000..78bb9ac145 --- /dev/null +++ b/dom/security/test/referrer-policy/referrer_helper.js @@ -0,0 +1,129 @@ +// This helper expects these globals to be defined. +/* global PARAMS, SJS, testCases */ + +/* + * common functionality for iframe, anchor, and area referrer attribute tests + */ +const GET_RESULT = SJS + "ACTION=get-test-results"; +const RESET_STATE = SJS + "ACTION=resetState"; + +SimpleTest.waitForExplicitFinish(); +var advance = function() { + tests.next(); +}; + +/** + * Listen for notifications from the child. + * These are sent in case of error, or when the loads we await have completed. + */ +window.addEventListener("message", function(event) { + if (event.data == "childLoadComplete") { + // all loads happen, continue the test. + advance(); + } +}); + +/** + * helper to perform an XHR + * to do checkIndividualResults and resetState + */ +function doXHR(aUrl, onSuccess, onFail) { + // The server is at http[s]://example.com so we need cross-origin XHR. + var xhr = new XMLHttpRequest({ mozSystem: true }); + xhr.responseType = "json"; + xhr.onload = function() { + onSuccess(xhr); + }; + xhr.onerror = function() { + onFail(xhr); + }; + xhr.open("GET", "http" + aUrl, true); + xhr.send(null); +} + +/** + * Grabs the results via XHR and passes to checker. + */ +function checkIndividualResults(aTestname, aExpectedReferrer, aName) { + var onload = xhr => { + var results = xhr.response; + info(JSON.stringify(xhr.response)); + ok(aName in results, aName + " tests have to be performed."); + is( + results[aName].policy, + aExpectedReferrer, + aTestname + + " --- " + + results[aName].policy + + " (" + + results[aName].referrer + + ")" + ); + advance(); + }; + var onerror = xhr => { + ok(false, "Can't get results from the counter server."); + SimpleTest.finish(); + }; + doXHR(GET_RESULT, onload, onerror); +} + +function resetState() { + doXHR(RESET_STATE, advance, function(xhr) { + ok(false, "error in reset state"); + SimpleTest.finish(); + }); +} + +/** + * testing if referrer header is sent correctly + */ +var tests = (function*() { + yield SpecialPowers.pushPrefEnv( + { set: [["network.preload", true]] }, + advance + ); + yield SpecialPowers.pushPrefEnv( + { set: [["security.mixed_content.block_active_content", false]] }, + advance + ); + yield SpecialPowers.pushPermissions( + [{ type: "systemXHR", allow: true, context: document }], + advance + ); + + var iframe = document.getElementById("testframe"); + + for (var j = 0; j < testCases.length; j++) { + if (testCases[j].PREFS) { + yield SpecialPowers.pushPrefEnv({ set: testCases[j].PREFS }, advance); + } + + var actions = testCases[j].ACTION; + var subTests = testCases[j].TESTS; + for (var k = 0; k < actions.length; k++) { + var actionString = actions[k]; + for (var i = 0; i < subTests.length; i++) { + yield resetState(); + var searchParams = new URLSearchParams(); + searchParams.append("ACTION", actionString); + searchParams.append("NAME", subTests[i].NAME); + for (var l of PARAMS) { + if (subTests[i][l]) { + searchParams.append(l, subTests[i][l]); + } + } + var schemeFrom = subTests[i].SCHEME_FROM || "http"; + yield (iframe.src = schemeFrom + SJS + searchParams.toString()); + yield checkIndividualResults( + subTests[i].DESC, + subTests[i].RESULT, + subTests[i].NAME + ); + } + } + } + + // complete. + SimpleTest.finish(); +})(); 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; +} diff --git a/dom/security/test/referrer-policy/test_img_referrer.html b/dom/security/test/referrer-policy/test_img_referrer.html new file mode 100644 index 0000000000..926c28de5e --- /dev/null +++ b/dom/security/test/referrer-policy/test_img_referrer.html @@ -0,0 +1,186 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test img policy attribute for Bug 1166910</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<!-- +Testing that img referrer attribute is honoured correctly +* Speculative parser loads (generate-img-policy-test) +* regular loads (generate-img-policy-test2) +* loading a single image multiple times with different policies (generate-img-policy-test3) +* testing setAttribute and .referrer (generate-setAttribute-test) +* regression tests that meta referrer is still working even if attribute referrers are enabled +https://bugzilla.mozilla.org/show_bug.cgi?id=1166910 +--> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * Listen for notifications from the child. + * These are sent in case of error, or when the loads we await have completed. + */ +window.addEventListener("message", function(event) { + if (event.data == "childLoadComplete" || + event.data.contains("childLoadComplete")) { + advance(); + } +}); + +/** + * helper to perform an XHR. + */ +function doXHR(aUrl, onSuccess, onFail) { + var xhr = new XMLHttpRequest(); + xhr.responseType = "json"; + xhr.onload = function () { + onSuccess(xhr); + }; + xhr.onerror = function () { + onFail(xhr); + }; + xhr.open('GET', aUrl, true); + xhr.send(null); +} + +/** + * Grabs the results via XHR and passes to checker. + */ +function checkIndividualResults(aTestname, aExpectedImg, aName) { + doXHR('/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=get-test-results', + function(xhr) { + var results = xhr.response; + info(JSON.stringify(xhr.response)); + + for (i in aName) { + ok(aName[i] in results.tests, aName[i] + " tests have to be performed."); + is(results.tests[aName[i]].policy, aExpectedImg[i], aTestname + ' --- ' + results.tests[aName[i]].policy + ' (' + results.tests[aName[i]].referrer + ')'); + } + + advance(); + }, + function(xhr) { + ok(false, "Can't get results from the counter server."); + SimpleTest.finish(); + }); +} + +function resetState() { + doXHR('/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=resetState', + advance, + function(xhr) { + ok(false, "error in reset state"); + SimpleTest.finish(); + }); +} + +/** + * testing if img referrer attribute is honoured (1165501) + */ +var tests = (function*() { + + var iframe = document.getElementById("testframe"); + var sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-img-policy-test"; + + // setting img unsafe-url and meta origin - unsafe-url shall prevail (should use speculative load) + yield resetState(); + var name = 'unsaf-url-with-meta-in-origin'; + yield iframe.src = sjs + "&imgPolicy=" + escape('unsafe-url') + "&name=" + name + "&policy=" + escape('origin'); + yield checkIndividualResults("unsafe-url (img) with origin in meta", ["full"], [name]); + + // setting img no-referrer and meta default - no-referrer shall prevail (should use speculative load) + yield resetState(); + name = 'no-referrer-with-meta-in-origin'; + yield iframe.src = sjs + "&imgPolicy=" + escape('no-referrer')+ "&name=" + name + "&policy=" + escape('origin'); + yield checkIndividualResults("no-referrer (img) with default in meta", ["none"], [name]); + + // test referrer policy in regular load + yield resetState(); + sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-img-policy-test2"; + name = 'regular-load-unsafe-url'; + yield iframe.src = sjs + "&imgPolicy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("unsafe-url in img", ["full"], [name]); + + // test referrer policy in regular load with multiple images + var policies = ['unsafe-url', 'origin', 'no-referrer']; + var expected = ["full", "origin", "none"]; + yield resetState(); + sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-img-policy-test3"; + name = 'multiple-images-'+policies[0]+'-'+policies[1]+'-'+policies[2]; + yield iframe.src = sjs + "&imgPolicy1=" + escape(policies[0]) + "&imgPolicy2=" + escape(policies[1]) + "&imgPolicy3=" + escape(policies[2]) + "&name=" + name; + yield checkIndividualResults(policies[0]+", "+policies[1]+" and "+policies[2]+" in img", expected, [name+policies[0], name+policies[1], name+policies[2]]); + + policies = ['origin', 'no-referrer', 'unsafe-url']; + expected = ["origin", "none", "full"]; + yield resetState(); + sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-img-policy-test3"; + name = 'multiple-images-'+policies[0]+'-'+policies[1]+'-'+policies[2]; + yield iframe.src = sjs + "&imgPolicy1=" + escape(policies[0]) + "&imgPolicy2=" + escape(policies[1]) + "&imgPolicy3=" + escape(policies[2]) + "&name=" + name; + yield checkIndividualResults(policies[0]+", "+policies[1]+" and "+policies[2]+" in img", expected, [name+policies[0], name+policies[1], name+policies[2]]); + + policies = ['no-referrer', 'origin', 'unsafe-url']; + expected = ["none", "origin", "full"]; + yield resetState(); + sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-img-policy-test3"; + name = 'multiple-images-'+policies[0]+'-'+policies[1]+'-'+policies[2]; + yield iframe.src = sjs + "&imgPolicy1=" + escape(policies[0]) + "&imgPolicy2=" + escape(policies[1]) + "&imgPolicy3=" + escape(policies[2]) + "&name=" + name; + yield checkIndividualResults(policies[0]+", "+policies[1]+" and "+policies[2]+" in img", expected, [name+policies[0], name+policies[1], name+policies[2]]); + + // regression tests that meta referrer is still working even if attribute referrers are enabled + yield resetState(); + sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-img-policy-test4"; + name = 'regular-load-no-referrer-meta'; + yield iframe.src = sjs + "&policy=" + escape('no-referrer') + "&name=" + name; + yield checkIndividualResults("no-referrer in meta (no img referrer policy), speculative load", ["none"], [name]); + + yield resetState(); + sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-img-policy-test5"; + name = 'regular-load-no-referrer-meta'; + yield iframe.src = sjs + "&policy=" + escape('no-referrer') + "&name=" + name; + yield checkIndividualResults("no-referrer in meta (no img referrer policy), regular load", ["none"], [name]); + + //test setAttribute + yield resetState(); + sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-setAttribute-test1"; + name = 'set-referrer-policy-attribute-before-src'; + yield iframe.src = sjs + "&imgPolicy=" + escape('no-referrer') + "&policy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("no-referrer in img", ["none"], [name]); + + yield resetState(); + sjs = "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-setAttribute-test2"; + name = 'set-referrer-policy-attribute-after-src'; + yield iframe.src = sjs + "&imgPolicy=" + escape('no-referrer') + "&policy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("no-referrer in img", ["none"], [name]); + + yield resetState(); + sjs = + "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-setAttribute-test2"; + name = 'set-invalid-referrer-policy-attribute-before-src-invalid'; + yield iframe.src = sjs + "&imgPolicy=" + escape('invalid') + "&policy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("unsafe-url in meta, invalid in img", ["full"], [name]); + + yield resetState(); + sjs = + "/tests/dom/security/test/referrer-policy/img_referrer_testserver.sjs?action=generate-setAttribute-test2"; + name = 'set-invalid-referrer-policy-attribute-before-src-invalid'; + yield iframe.src = sjs + "&imgPolicy=" + escape('default') + "&policy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("unsafe-url in meta, default in img", ["full"], [name]); + + // complete. + SimpleTest.finish(); +})(); + +</script> +</head> + +<body onload="tests.next();"> + <iframe id="testframe"></iframe> + +</body> +</html> + diff --git a/dom/security/test/referrer-policy/test_referrer_header_current_document.html b/dom/security/test/referrer-policy/test_referrer_header_current_document.html new file mode 100644 index 0000000000..3d0ac02cc5 --- /dev/null +++ b/dom/security/test/referrer-policy/test_referrer_header_current_document.html @@ -0,0 +1,26 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test referrer header not affecting document.referrer for current document for Bug 1601743</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + + <!-- + Testing that navigating to a document with Referrer-Policy:same-origin doesn't affect + the value of document.referrer for that document. + https://bugzilla.mozilla.org/show_bug.cgi?id=1601743 + --> + + <script type="application/javascript"> + const IFRAME_URL = `${location.origin}/tests/dom/security/test/referrer-policy/referrer_header_current_document_iframe.html`; + SimpleTest.waitForExplicitFinish(); + window.addEventListener("message", (event) => { + SimpleTest.is(event.data, IFRAME_URL, "Must have the original iframe as the referrer!"); + SimpleTest.finish(); + }, { once: true }); + </script> +</head> + +<body> +<iframe src="referrer_header_current_document_iframe.html"></iframe> +</body> diff --git a/dom/security/test/referrer-policy/test_referrer_redirect.html b/dom/security/test/referrer-policy/test_referrer_redirect.html new file mode 100644 index 0000000000..e6bd82fced --- /dev/null +++ b/dom/security/test/referrer-policy/test_referrer_redirect.html @@ -0,0 +1,123 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test anchor and area policy attribute for Bug 1184781</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing referrer headers after redirects. + https://bugzilla.mozilla.org/show_bug.cgi?id=1184781 + --> + + <script type="application/javascript"> + + const SJS = "://example.com/tests/dom/security/test/referrer-policy/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "RP_HEADER"]; + + const testCases = [ + {ACTION: ["generate-img-redirect-policy-test", "generate-iframe-redirect-policy-test"], + TESTS: [ + { + ATTRIBUTE_POLICY: "no-referrer", + NAME: "no-referrer-with-no-meta", + DESC: "no-referrer (img/iframe) with no meta", + RESULT: "none" + }, + { + ATTRIBUTE_POLICY: "origin", + NAME: "origin-with-no-meta", + DESC: "origin (img/iframe) with no meta", + RESULT: "origin" + }, + { + ATTRIBUTE_POLICY: "unsafe-url", + NAME: "unsafe-url-with-no-meta", + DESC: "unsafe-url (img/iframe) with no meta", + RESULT: "full" + }, + { + META_POLICY: "unsafe-url", + NAME: "unsafe-url-in-meta", + DESC: "unsafe-url in meta", + RESULT: "full" + }, + { + META_POLICY: "origin", + NAME: "origin-in-meta", + DESC: "origin in meta", + RESULT: "origin" + }, + { + META_POLICY: "no-referrer", + NAME: "no-referrer-in-meta", + DESC: "no-referrer in meta", + RESULT: "none" + }, + { + META_POLICY: "origin-when-cross-origin", + NAME: "origin-when-cross-origin-in-meta", + DESC: "origin-when-cross-origin in meta", + RESULT: "origin" + }, + { + ATTRIBUTE_POLICY: "no-referrer", + RP_HEADER: "origin", + NAME: "no-referrer-with-no-meta-origin-RP-header", + DESC: "no-referrer (img/iframe) with no meta, origin Referrer-Policy redirect header", + RESULT: "none" + }, + { + ATTRIBUTE_POLICY: "origin", + RP_HEADER: "no-referrer", + NAME: "origin-with-no-meta-no-referrer-RP-header", + DESC: "origin (img/iframe) with no meta, no-referrer Referrer-Policy redirect header", + RESULT: "none" + }, + { + ATTRIBUTE_POLICY: "unsafe-url", + RP_HEADER: "origin", + NAME: "unsafe-url-with-no-meta-origin-RP-header", + DESC: "unsafe-url (img/iframe) with no meta, origin Referrer-Policy redirect header", + RESULT: "origin" + }, + { + META_POLICY: "unsafe-url", + RP_HEADER: "origin", + NAME: "unsafe-url-in-meta-origin-RP-header", + DESC: "unsafe-url in meta, origin Referrer-Policy redirect header", + RESULT: "origin" + }, + { + META_POLICY: "origin", + RP_HEADER: "no-referrer", + NAME: "origin-in-meta-no-referrer-RP-header", + DESC: "origin in meta, no-referrer Referrer-Policy redirect header", + RESULT: "none" + }, + { + META_POLICY: "no-referrer", + RP_HEADER: "origin", + NAME: "no-referrer-in-meta-origin-RP-header", + DESC: "no-referrer in meta, origin Referrer-Policy redirect header", + RESULT: "none" + }, + { + META_POLICY: "origin-when-cross-origin", + RP_HEADER: "unsafe-url", + NAME: "origin-when-cross-origin-in-meta-unsafe-url-RP-header", + DESC: "origin-when-cross-origin in meta, unsafe-url Referrer-Policy redirect header", + RESULT: "origin" + } + ] + } + ]; + </script> + <script type="application/javascript" src="/tests/dom/security/test/referrer-policy/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> + |