Bug 1165501 - using most recent referrer policy found in the document. r=sstamm

--HG--
extra : rebase_source : 1513da5ff6a896ab4987323354458004b5ddb787
This commit is contained in:
Franziskus Kiefer 2015-05-27 13:29:00 -07:00
parent 8e863f2bce
commit 657c062d2a
6 changed files with 94 additions and 45 deletions

View File

@ -2976,19 +2976,10 @@ nsDocument::InitCSP(nsIChannel* aChannel)
rv = csp->GetReferrerPolicy(&referrerPolicy, &hasReferrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
if (hasReferrerPolicy) {
// Referrer policy spec (section 6.1) says that once the referrer policy
// is set, any future attempts to change it result in No-Referrer.
if (!mReferrerPolicySet) {
mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
mReferrerPolicySet = true;
} else if (mReferrerPolicy != referrerPolicy) {
mReferrerPolicy = mozilla::net::RP_No_Referrer;
{
MOZ_LOG(gCspPRLog, PR_LOG_DEBUG, ("%s %s",
"CSP wants to set referrer, but nsDocument"
"already has it set. No referrers will be sent"));
}
}
// Referrer policy spec (section 6.1) says that we always use the newest
// referrer policy we find
mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
mReferrerPolicySet = true;
// Referrer Policy is set separately for the speculative parser in
// nsHTMLDocument::StartDocumentLoad() so there's nothing to do here for
@ -3776,14 +3767,10 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
if (aHeaderField == nsGkAtoms::referrer && !aData.IsEmpty()) {
ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aData);
// Referrer policy spec (section 6.1) says that once the referrer policy
// is set, any future attempts to change it result in No-Referrer.
if (!mReferrerPolicySet) {
mReferrerPolicy = policy;
mReferrerPolicySet = true;
} else if (mReferrerPolicy != policy) {
mReferrerPolicy = mozilla::net::RP_No_Referrer;
}
// Referrer policy spec (section 6.1) says that we always use the newest
// referrer policy we find
mReferrerPolicy = policy;
mReferrerPolicySet = true;
}
}

View File

@ -44,17 +44,23 @@ function create2ndLevelIframeUrl(schemeFrom, schemeTo, policy, type) {
// loaded. The click triggers a redirection to file_bug704320_redirect.html,
// which in turn notifies the main window that it's time to check the test
// results.
function createTest(schemeFrom, schemeTo, policy) {
function createTest(schemeFrom, schemeTo, policy, optionalEarlierPolicy) {
var _createTestUrl = createTestUrl.bind(
null, schemeFrom, schemeTo, policy, 'test');
var _create2ndLevelIframeUrl = create2ndLevelIframeUrl.bind(
null, schemeFrom, schemeTo, policy);
var metaReferrerPolicyString = '';
if (optionalEarlierPolicy && optionalEarlierPolicy != '') {
metaReferrerPolicyString += '<meta name="referrer" content="' + optionalEarlierPolicy + '">\n';
}
metaReferrerPolicyString += '<meta name="referrer" content="' + policy + '">';
return '<!DOCTYPE HTML>\n\
<html>\n\
<head>\n\
<meta name="referrer" content="' + policy + '">\n\
'+metaReferrerPolicyString+'\n\
<link rel="stylesheet" type="text/css" href="' + _createTestUrl('stylesheet') + '">\n\
<style type="text/css">\n\
@import "' + _createTestUrl('import-css') + '";\n\
@ -165,11 +171,17 @@ function createIframedWindowLocationTest(schemeFrom, schemeTo, policy) {
</html>';
}
function createPolicyTest(refpol) {
function createPolicyTest(policy, optionalEarlierPolicy) {
var metaReferrerPolicyString = '';
if (optionalEarlierPolicy && optionalEarlierPolicy != '') {
metaReferrerPolicyString += '<meta name="referrer" content="' + optionalEarlierPolicy + '">\n';
}
metaReferrerPolicyString += '<meta name="referrer" content="' + policy + '">';
return '<!DOCTYPE HTML>\n\
<html>\n\
<head>\n\
<meta name="referrer" content="' + refpol + '">\n\
'+metaReferrerPolicyString+'\n\
<script type="text/javascript" src="/tests/dom/base/test/file_bug704320_preload_common.js"></script>\n\
</head>\n\
<body>\n\
@ -191,10 +203,14 @@ function handleRequest(request, response) {
var schemeFrom = params[1].split('=')[1];
var schemeTo = params[2].split('=')[1];
var policy = params[3].split('=')[1];
var optionalEarlierPolicy = '';
if (params[4]) {
optionalEarlierPolicy = params[4].split('=')[1];
}
response.setHeader('Content-Type', 'text/html; charset=utf-8', false);
response.setHeader('Cache-Control', 'no-cache', false);
response.write(createTest(schemeFrom, schemeTo, policy));
response.write(createTest(schemeFrom, schemeTo, policy, optionalEarlierPolicy));
}
else if (action === 'create-2nd-level-iframe') {
// ?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=origin&type=form"
@ -266,7 +282,12 @@ function handleRequest(request, response) {
// ?action=generate-policy-test&policy=b64-encoded-string
response.setHeader('Cache-Control', 'no-cache', false);
response.setHeader('Content-Type', 'text/html', false);
var refpol = unescape(params[1].split('=')[1]);
response.write(createPolicyTest(refpol));
var policy = unescape(params[1].split('=')[1]);
var optionalEarlierPolicy = '';
if (params[2]) {
optionalEarlierPolicy = params[2].split('=')[1];
}
response.write(createPolicyTest(policy, optionalEarlierPolicy));
}
}

View File

@ -678,6 +678,8 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
[test_bug1163743.html]
support-files = referrerHelper.js
[test_bug1165501.html]
support-files = referrerHelper.js
[test_caretPositionFromPoint.html]
[test_classList.html]
# This test fails on the Mac for some reason

View File

@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<html>
<!--
Spot test to see if newer meta-referrer policy is used
https://bugzilla.mozilla.org/show_bug.cgi?id=1165501
-->
<head>
<meta charset="utf-8">
<title>Test policies for Bug 1165501</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="referrerHelper.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.7">
SimpleTest.waitForExplicitFinish();
var advance = function() { tests.next(); };
/**
* testing if policy is overwritten if there are two meta statements (1165501)
* XXX: would be nice to test this with CSP and meta as well
*/
var tests = (function() {
var iframe = document.getElementById("testframe");
const sjs = "/tests/dom/base/test/bug704320.sjs?action=generate-policy-test";
// setting first unsafe-url and then origin - origin shall prevail
yield resetCounter();
yield iframe.src = sjs + "&policy=" + escape('origin')+ "&wrongPolicy=" + escape('unsafe-url');
yield checkIndividualResults("unsafe-url then origin", ["origin"]);
// setting first no-referrer and then default - default shall prevail
yield resetCounter();
yield iframe.src = sjs + "&policy=" + escape('default')+ "&wrongPolicy=" + escape('no-referrer');
yield checkIndividualResults("no-referrer then default", ["full"]);
// complete. Be sure to yield so we don't call this twice.
yield SimpleTest.finish();
})();
</script>
</head>
<body onload="tests.next();">
<iframe id="testframe"></iframe>
</body>
</html>

View File

@ -63,7 +63,6 @@ static nsITimer* gFlushTimer = nullptr;
nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor()
: nsHtml5DocumentBuilder(false)
, mPreloadedURLs(23) // Mean # of preloadable resources per page on dmoz
, mSpeculationReferrerPolicyWasSet(false)
, mSpeculationReferrerPolicy(mozilla::net::RP_Default)
{
// zeroing operator new for everything else
@ -1010,20 +1009,10 @@ nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(const nsAString& aReferrerPo
void
nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy)
{
if (mSpeculationReferrerPolicyWasSet &&
aReferrerPolicy != mSpeculationReferrerPolicy) {
// According to the Referrer Policy spec, if there's already been a policy
// set and another attempt is made to set a _different_ policy, the result
// is a "No Referrer" policy.
mSpeculationReferrerPolicy = mozilla::net::RP_No_Referrer;
}
else {
// Record "speculated" referrer policy locally and thread through the
// speculation phase. The actual referrer policy will be set by
// HTMLMetaElement::BindToTree().
mSpeculationReferrerPolicyWasSet = true;
mSpeculationReferrerPolicy = aReferrerPolicy;
}
// Record "speculated" referrer policy locally and thread through the
// speculation phase. The actual referrer policy will be set by
// HTMLMetaElement::BindToTree().
mSpeculationReferrerPolicy = aReferrerPolicy;
}
#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH

View File

@ -68,9 +68,8 @@ class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
nsCOMPtr<nsIURI> mSpeculationBaseURI;
/**
* Need to keep track of whether the referrer policy was already set.
* Speculative referrer policy
*/
bool mSpeculationReferrerPolicyWasSet;
ReferrerPolicy mSpeculationReferrerPolicy;
nsCOMPtr<nsIURI> mViewSourceBaseURI;