mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1857894 - Recalculate referrer based on original referrer after non-HSTS HTTPS upgrade r=necko-reviewers,freddyb,kershaw
Per fetch spec [1], we should perform CSP upgrade-insecure-requests and mixed content upgrades before determining the referrer, while HSTS upgrades happen after the referrer is determined. In our implementation, we determine the referrer before all the upgrades, so we need to recalculate the referrer after we upgrade through anything but HSTS. [1] https://fetch.spec.whatwg.org/#main-fetch Differential Revision: https://phabricator.services.mozilla.com/D193417
This commit is contained in:
parent
ad91a46064
commit
7c11f39184
@ -13,6 +13,15 @@ This Test is split into two for Bug 1453396
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
// We do not want HTTPS upgrades to interfere with this test. For that,
|
||||
// see dom/security/test/referrer-policy/test_referrer_redirect.html.
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.security.https_first", false],
|
||||
["security.mixed_content.upgrade_display_content", false]
|
||||
],
|
||||
});
|
||||
|
||||
//generates URLs to test
|
||||
var generateURLArray = (function(from, to){
|
||||
const baseURL = '://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=';
|
||||
|
@ -18,6 +18,10 @@
|
||||
|
||||
const testCases = [
|
||||
{ACTION: ["generate-link-policy-test"],
|
||||
PREFS: [
|
||||
["dom.security.https_first", false],
|
||||
["security.mixed_content.upgrade_display_content", false]
|
||||
],
|
||||
TESTS: [
|
||||
{ATTRIBUTE_POLICY: 'unsafe-url',
|
||||
NAME: 'preload-unsafe-url-with-origin-in-meta',
|
||||
@ -209,6 +213,76 @@
|
||||
DESC: "preload-unsafe-url-property (orginally origin) with no-referrer in meta",
|
||||
RESULT: 'full'},
|
||||
]},
|
||||
{
|
||||
// All previos tests with SCHEME_FROM: 'https' and SCHEME_TO: 'http',
|
||||
// this time with mixed content upgrading enabled.
|
||||
ACTION: ["generate-link-policy-test"],
|
||||
PREFS: [
|
||||
["dom.security.https_first", false],
|
||||
["security.mixed_content.upgrade_display_content", true]
|
||||
],
|
||||
TESTS: [
|
||||
// Downgrade.
|
||||
{ATTRIBUTE_POLICY: 'no-referrer-when-downgrade',
|
||||
NAME: 'preload-origin-in-meta-downgrade-in-attr-upgraded',
|
||||
META_POLICY: 'origin',
|
||||
DESC: 'preload-origin in meta downgrade in attr (upgraded)',
|
||||
REL: 'preload',
|
||||
SCHEME_FROM: 'https',
|
||||
SCHEME_TO: 'http',
|
||||
RESULT: 'full'},
|
||||
{ATTRIBUTE_POLICY: 'strict-origin',
|
||||
NAME: 'preload-origin-in-meta-strict-origin-in-attr-upgraded',
|
||||
META_POLICY: 'origin',
|
||||
DESC: 'preload-origin in meta strict-origin in attr (upgraded)',
|
||||
REL: 'preload',
|
||||
SCHEME_FROM: 'https',
|
||||
SCHEME_TO: 'http',
|
||||
RESULT: 'origin'},
|
||||
{ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin',
|
||||
NAME: 'preload-origin-in-meta-strict-origin-when-cross-origin-in-attr-upgraded',
|
||||
META_POLICY: 'origin',
|
||||
DESC: 'preload-origin in meta strict-origin-when-cross-origin in attr (upgraded)',
|
||||
REL: 'preload',
|
||||
SCHEME_FROM: 'https',
|
||||
SCHEME_TO: 'http',
|
||||
RESULT: 'full'},
|
||||
|
||||
// Cross origin
|
||||
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
|
||||
NAME: 'preload-origin-when-cross-origin-with-no-meta-upgraded',
|
||||
META_POLICY: '',
|
||||
SCHEME_FROM: 'https',
|
||||
SCHEME_TO: 'http',
|
||||
REL: 'preload',
|
||||
DESC: "preload-origin-when-cross-origin with no meta (upgraded)",
|
||||
RESULT: 'full'},
|
||||
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
|
||||
NAME: 'preload-origin-when-cross-origin-with-no-referrer-in-meta-upgraded',
|
||||
META_POLICY: 'no-referrer',
|
||||
SCHEME_FROM: 'https',
|
||||
SCHEME_TO: 'http',
|
||||
REL: 'preload',
|
||||
DESC: "preload-origin-when-cross-origin with no-referrer in meta (upgraded)",
|
||||
RESULT: 'full'},
|
||||
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
|
||||
NAME: 'preload-origin-when-cross-origin-with-unsafe-url-in-meta-upgraded-upgraded',
|
||||
META_POLICY: 'unsafe-url',
|
||||
SCHEME_FROM: 'https',
|
||||
SCHEME_TO: 'http',
|
||||
REL: 'preload',
|
||||
DESC: "preload-origin-when-cross-origin with unsafe-url in meta (upgraded)",
|
||||
RESULT: 'full'},
|
||||
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
|
||||
NAME: 'preload-origin-when-cross-origin-with-origin-in-meta-upgraded-upgraded',
|
||||
META_POLICY: 'origin',
|
||||
SCHEME_FROM: 'https',
|
||||
SCHEME_TO: 'http',
|
||||
REL: 'preload',
|
||||
DESC: "preload-origin-when-cross-origin with origin in meta (upgraded)",
|
||||
RESULT: 'full'},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
</script>
|
||||
|
@ -1228,21 +1228,6 @@ ReferrerInfo::InitWithElement(const Element* aElement) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsIReferrerInfo>
|
||||
ReferrerInfo::CreateFromOtherAndPolicyOverride(
|
||||
nsIReferrerInfo* aOther, ReferrerPolicyEnum aPolicyOverride) {
|
||||
MOZ_ASSERT(aOther);
|
||||
ReferrerPolicyEnum policy = aPolicyOverride != ReferrerPolicy::_empty
|
||||
? aPolicyOverride
|
||||
: aOther->ReferrerPolicy();
|
||||
|
||||
nsCOMPtr<nsIURI> referrer = aOther->GetComputedReferrer();
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo =
|
||||
new ReferrerInfo(referrer, policy, aOther->GetSendReferrer());
|
||||
return referrerInfo.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsIReferrerInfo>
|
||||
ReferrerInfo::CreateFromDocumentAndPolicyOverride(
|
||||
|
@ -93,16 +93,6 @@ class ReferrerInfo : public nsIReferrerInfo {
|
||||
// Record the telemetry for the referrer policy.
|
||||
void RecordTelemetry(nsIHttpChannel* aChannel);
|
||||
|
||||
/*
|
||||
* Helper function to create a new ReferrerInfo object from other. We will not
|
||||
* pass in any computed values and override referrer policy if needed
|
||||
*
|
||||
* @param aOther the other referrerInfo object to init from.
|
||||
* @param aPolicyOverride referrer policy to override if necessary.
|
||||
*/
|
||||
static already_AddRefed<nsIReferrerInfo> CreateFromOtherAndPolicyOverride(
|
||||
nsIReferrerInfo* aOther, ReferrerPolicyEnum aPolicyOverride);
|
||||
|
||||
/*
|
||||
* Helper function to create a new ReferrerInfo object from a given document
|
||||
* and override referrer policy if needed (for example, when parsing link
|
||||
|
@ -12,6 +12,7 @@ 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" +
|
||||
@ -266,7 +267,7 @@ function createTargetBlankRefferer(
|
||||
}
|
||||
|
||||
// creates test page with img that is a redirect
|
||||
function createRedirectImgTestCase(aParams, aAttributePolicy) {
|
||||
function createImgTestCase(aParams, aAttributePolicy, aRedirect) {
|
||||
var metaString = "";
|
||||
if (aParams.has("META_POLICY")) {
|
||||
metaString = `<meta name="referrer" content="${aParams.get(
|
||||
@ -274,8 +275,16 @@ function createRedirectImgTestCase(aParams, aAttributePolicy) {
|
||||
)}">`;
|
||||
}
|
||||
aParams.delete("ACTION");
|
||||
aParams.append("ACTION", "redirectImg");
|
||||
var imgUrl = "http://" + CROSS_ORIGIN_URL + aParams.toString();
|
||||
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>
|
||||
@ -637,7 +646,7 @@ function handleRequest(request, response) {
|
||||
|
||||
// redirect tests with img and iframe
|
||||
if (action === "generate-img-redirect-policy-test") {
|
||||
response.write(createRedirectImgTestCase(params, attributePolicy));
|
||||
response.write(createImgTestCase(params, attributePolicy, true));
|
||||
return;
|
||||
}
|
||||
if (action === "generate-iframe-redirect-policy-test") {
|
||||
@ -655,6 +664,11 @@ function handleRequest(request, response) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === "generate-img-policy-test") {
|
||||
response.write(createImgTestCase(params, attributePolicy, false));
|
||||
return;
|
||||
}
|
||||
|
||||
_getPage = createLinkPageUsingRefferer.bind(
|
||||
null,
|
||||
metaPolicy,
|
||||
|
@ -14,7 +14,7 @@
|
||||
<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 PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "RP_HEADER", "HSTS"];
|
||||
|
||||
const testCases = [
|
||||
{ACTION: ["generate-img-redirect-policy-test", "generate-iframe-redirect-policy-test"],
|
||||
@ -111,6 +111,51 @@
|
||||
RESULT: "origin"
|
||||
}
|
||||
]
|
||||
},
|
||||
// Check that "internal" redirects for mixed content upgrading
|
||||
// are invisible, but not for HSTS upgrades (Bug 1857894).
|
||||
{
|
||||
ACTION: ["generate-img-policy-test"],
|
||||
PREFS: [["security.mixed_content.upgrade_display_content", true]],
|
||||
TESTS: [
|
||||
{
|
||||
META_POLICY: "strict-origin",
|
||||
NAME: "img-strict-origin-mixed-content-upgrade",
|
||||
DESC: "img-strict-origin-mixed-content-upgrade",
|
||||
SCHEME_FROM: "https",
|
||||
RESULT: "other-origin",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
ACTION: ["generate-img-policy-test"],
|
||||
PREFS: [["security.mixed_content.upgrade_display_content", false]],
|
||||
TESTS: [
|
||||
{
|
||||
META_POLICY: "strict-origin",
|
||||
NAME: "img-strict-origin-mixed-content-no-upgrade",
|
||||
DESC: "img-strict-origin-mixed-content-no-upgrade",
|
||||
SCHEME_FROM: "https",
|
||||
RESULT: "none",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
ACTION: ["generate-img-policy-test"],
|
||||
PREFS: [
|
||||
["security.mixed_content.upgrade_display_content", false],
|
||||
["network.stricttransportsecurity.preloadlist", true],
|
||||
],
|
||||
TESTS: [
|
||||
{
|
||||
META_POLICY: "strict-origin",
|
||||
NAME: "img-strict-origin-hsts-upgrade",
|
||||
DESC: "img-strict-origin-hsts-upgrade",
|
||||
SCHEME_FROM: "https",
|
||||
RESULT: "none",
|
||||
HSTS: true,
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
@ -4561,14 +4561,25 @@ HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
|
||||
dom::ReferrerInfo::ReferrerPolicyFromHeaderString(tRPHeaderValue);
|
||||
}
|
||||
|
||||
if (referrerPolicy != dom::ReferrerPolicy::_empty) {
|
||||
// We may reuse computed referrer in redirect, so if referrerPolicy
|
||||
// changes, we must not use the old computed value, and have to compute
|
||||
// again.
|
||||
nsCOMPtr<nsIReferrerInfo> referrerInfo =
|
||||
dom::ReferrerInfo::CreateFromOtherAndPolicyOverride(mReferrerInfo,
|
||||
referrerPolicy);
|
||||
config.referrerInfo = referrerInfo;
|
||||
// In case we are here because an upgrade happened through mixed content
|
||||
// upgrading, CSP upgrade-insecure-requests, HTTPS-Only or HTTPS-First, we
|
||||
// have to recalculate the referrer based on the original referrer to
|
||||
// account for the different scheme. This does NOT apply to HSTS.
|
||||
// See Bug 1857894 and order of https://fetch.spec.whatwg.org/#main-fetch.
|
||||
// Otherwise, if we have a new referrer policy, we want to recalculate the
|
||||
// referrer based on the old computed referrer (Bug 1678545).
|
||||
bool wasNonHSTSUpgrade =
|
||||
(aRedirectFlags & nsIChannelEventSink::REDIRECT_STS_UPGRADE) &&
|
||||
(!mLoadInfo->GetHstsStatus());
|
||||
if (wasNonHSTSUpgrade) {
|
||||
nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetOriginalReferrer();
|
||||
config.referrerInfo =
|
||||
new dom::ReferrerInfo(referrer, mReferrerInfo->ReferrerPolicy(),
|
||||
mReferrerInfo->GetSendReferrer());
|
||||
} else if (referrerPolicy != dom::ReferrerPolicy::_empty) {
|
||||
nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetComputedReferrer();
|
||||
config.referrerInfo = new dom::ReferrerInfo(
|
||||
referrer, referrerPolicy, mReferrerInfo->GetSendReferrer());
|
||||
} else {
|
||||
config.referrerInfo = mReferrerInfo;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user