author | Gurzau Raul <rgurzau@mozilla.com> |
Tue, 09 Jul 2019 18:17:15 +0300 | |
changeset 542404 | 450801fafd10d18e6fce669408c551593b2028a7 |
parent 542403 | 06d4b70144ff6e923f61b06d4164b9eda977c8cb |
child 542405 | c9206e361572d5b404fc34590793f87ee4592703 |
push id | 11848 |
push user | ffxbld-merge |
push date | Mon, 26 Aug 2019 19:26:25 +0000 |
treeherder | mozilla-beta@9b31bfdfac10 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1557346 |
milestone | 70.0a1 |
backs out | 9ba600ae3c02a21a273596f2c98a2c47b0ee7c6e |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/locales/en-US/chrome/security/security.properties +++ b/dom/locales/en-US/chrome/security/security.properties @@ -115,13 +115,8 @@ ReportingHeaderInvalidEndpoint=Reporting Header: ignoring invalid endpoint for item named “%S”. # LOCALIZATION NOTE(ReportingHeaderInvalidURLEndpoint): %1$S is the invalid URL, %2$S is the group name ReportingHeaderInvalidURLEndpoint=Reporting Header: ignoring invalid endpoint URL “%1$S” for item named “%2$S”. FeaturePolicyUnsupportedFeatureName=Feature Policy: Skipping unsupported feature name “%S”. # TODO: would be nice to add a link to the Feature-Policy MDN documentation here. See bug 1449501 FeaturePolicyInvalidEmptyAllowValue= Feature Policy: Skipping empty allow list for feature: “%S”. # TODO: would be nice to add a link to the Feature-Policy MDN documentation here. See bug 1449501 FeaturePolicyInvalidAllowValue=Feature Policy: Skipping unsupported allow value “%S”. - -# LOCALIZATION NOTE: "%1$S" is the limitation length (bytes) of referrer URI, "%2$S" is the origin of the referrer URI. -ReferrerLengthOverLimitation=HTTP Referrer header: Length is over "%1$S" bytes limit - stripping referrer header down to origin: “%2$S” -# LOCALIZATION NOTE: "%1$S" is the limitation length (bytes) of referrer URI, "%2$S" is the origin of the referrer URI. -ReferrerOriginLengthOverLimitation=HTTP Referrer header: Length of origin within referrer is over "%1$S" bytes limit - removing referrer with origin "%2$S".
--- a/dom/security/ReferrerInfo.cpp +++ b/dom/security/ReferrerInfo.cpp @@ -6,16 +6,17 @@ #include "nsIClassInfoImpl.h" #include "nsICookieService.h" #include "nsIHttpChannel.h" #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" #include "nsIURIFixup.h" #include "nsIURL.h" +#include "nsIURIMutator.h" #include "nsWhitespaceTokenizer.h" #include "nsAlgorithm.h" #include "nsContentUtils.h" #include "ReferrerInfo.h" #include "mozilla/AntiTrackingCommon.h" #include "mozilla/net/CookieSettings.h" @@ -37,18 +38,16 @@ NS_IMPL_CLASSINFO(ReferrerInfo, nullptr, NS_IMPL_ISUPPORTS_CI(ReferrerInfo, nsIReferrerInfo, nsISerializable) #define DEFAULT_RP 3 #define DEFAULT_TRACKER_RP 3 #define DEFAULT_PRIVATE_RP 2 #define DEFAULT_TRACKER_PRIVATE_RP 2 -#define DEFAULT_REFERRER_HEADER_LENGTH_LIMIT 4096 - #define MAX_REFERRER_SENDING_POLICY 2 #define MAX_CROSS_ORIGIN_SENDING_POLICY 2 #define MAX_TRIMMING_POLICY 2 #define MIN_REFERRER_SENDING_POLICY 0 #define MIN_CROSS_ORIGIN_SENDING_POLICY 0 #define MIN_TRIMMING_POLICY 0 @@ -58,33 +57,29 @@ static uint32_t defaultPrivateRp = DEFAU static uint32_t defaultTrackerPrivateRp = DEFAULT_TRACKER_PRIVATE_RP; static bool sUserSpoofReferrerSource = false; static bool sUserHideOnionReferrerSource = false; static uint32_t sUserReferrerSendingPolicy = 0; static uint32_t sUserXOriginSendingPolicy = 0; static uint32_t sUserTrimmingPolicy = 0; static uint32_t sUserXOriginTrimmingPolicy = 0; -static uint32_t sReferrerHeaderLimit = DEFAULT_REFERRER_HEADER_LENGTH_LIMIT; static void CachePreferrenceValue() { static bool sPrefCached = false; if (sPrefCached) { return; } Preferences::AddBoolVarCache(&sUserSpoofReferrerSource, "network.http.referer.spoofSource"); Preferences::AddBoolVarCache(&sUserHideOnionReferrerSource, "network.http.referer.hideOnionSource"); Preferences::AddUintVarCache(&sUserReferrerSendingPolicy, "network.http.sendRefererHeader"); - Preferences::AddUintVarCache(&sReferrerHeaderLimit, - "network.http.referer.referrerLengthLimit", - DEFAULT_REFERRER_HEADER_LENGTH_LIMIT); sUserReferrerSendingPolicy = clamped<uint32_t>(sUserReferrerSendingPolicy, MIN_REFERRER_SENDING_POLICY, MAX_REFERRER_SENDING_POLICY); Preferences::AddUintVarCache(&sUserXOriginSendingPolicy, "network.http.referer.XOriginPolicy"); sUserXOriginSendingPolicy = clamped<uint32_t>( sUserXOriginSendingPolicy, MIN_CROSS_ORIGIN_SENDING_POLICY, @@ -482,165 +477,80 @@ ReferrerInfo::TrimmingPolicy ReferrerInf default: MOZ_ASSERT_UNREACHABLE("Unexpected value"); break; } return static_cast<TrimmingPolicy>(trimmingPolicy); } -nsresult ReferrerInfo::LimitReferrerLength( - nsIHttpChannel* aChannel, nsIURI* aReferrer, TrimmingPolicy aTrimmingPolicy, - nsACString& aInAndOutTrimmedReferrer) const { - if (!sReferrerHeaderLimit) { - return NS_OK; - } - - if (aInAndOutTrimmedReferrer.Length() <= sReferrerHeaderLimit) { - return NS_OK; +nsresult ReferrerInfo::TrimReferrerWithPolicy(nsCOMPtr<nsIURI>& aReferrer, + TrimmingPolicy aTrimmingPolicy, + nsACString& aResult) const { + if (aTrimmingPolicy == TrimmingPolicy::ePolicyFullURI) { + // use the full URI + return aReferrer->GetAsciiSpec(aResult); } - nsAutoString referrerLengthLimit; - referrerLengthLimit.AppendInt(sReferrerHeaderLimit); - if (aTrimmingPolicy == ePolicyFullURI || - aTrimmingPolicy == ePolicySchemeHostPortPath) { - // If referrer header is over max Length, down to origin - nsresult rv = GetOriginFromReferrerURI(aReferrer, aInAndOutTrimmedReferrer); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - // Step 6 within https://w3c.github.io/webappsec-referrer-policy/#strip-url - // states that the trailing "/" does not need to get stripped. However, - // GetOriginFromReferrerURI() also removes any trailing "/" hence we have to - // add it back here. - aInAndOutTrimmedReferrer.AppendLiteral("/"); - if (aInAndOutTrimmedReferrer.Length() <= sReferrerHeaderLimit) { - AutoTArray<nsString, 2> params = { - referrerLengthLimit, NS_ConvertUTF8toUTF16(aInAndOutTrimmedReferrer)}; - LogMessageToConsole(aChannel, "ReferrerLengthOverLimitation", params); - return NS_OK; - } - } - - // If we end up here either the trimmingPolicy is equal to - // 'ePolicySchemeHostPort' or the 'origin' of any other policy is still over - // the length limit. If so, truncate the referrer entirely. - AutoTArray<nsString, 2> params = { - referrerLengthLimit, NS_ConvertUTF8toUTF16(aInAndOutTrimmedReferrer)}; - LogMessageToConsole(aChannel, "ReferrerOriginLengthOverLimitation", params); - aInAndOutTrimmedReferrer.Truncate(); - - return NS_OK; -} - -nsresult ReferrerInfo::GetOriginFromReferrerURI(nsIURI* aReferrer, - nsACString& aResult) const { - MOZ_ASSERT(aReferrer); - aResult.Truncate(); - // We want the IDN-normalized PrePath. That's not something currently + // All output strings start with: scheme+host+port + // We want the IDN-normalized PrePath. That's not something currently // available and there doesn't yet seem to be justification for adding it to - // the interfaces, so just build it up from scheme+AsciiHostPort + // the interfaces, so just build it up ourselves from scheme+AsciiHostPort nsAutoCString scheme, asciiHostPort; nsresult rv = aReferrer->GetScheme(scheme); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - aResult = scheme; aResult.AppendLiteral("://"); // Note we explicitly cleared UserPass above, so do not need to build it. rv = aReferrer->GetAsciiHostPort(asciiHostPort); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - aResult.Append(asciiHostPort); - return NS_OK; -} - -nsresult ReferrerInfo::TrimReferrerWithPolicy(nsIURI* aReferrer, - TrimmingPolicy aTrimmingPolicy, - nsACString& aResult) const { - MOZ_ASSERT(aReferrer); - if (aTrimmingPolicy == TrimmingPolicy::ePolicyFullURI) { - return aReferrer->GetAsciiSpec(aResult); - } - - nsresult rv = GetOriginFromReferrerURI(aReferrer, aResult); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (aTrimmingPolicy == TrimmingPolicy::ePolicySchemeHostPortPath) { - nsCOMPtr<nsIURL> url(do_QueryInterface(aReferrer)); - if (url) { - nsAutoCString path; - rv = url->GetFilePath(path); + switch (aTrimmingPolicy) { + case TrimmingPolicy::ePolicySchemeHostPortPath: { + nsCOMPtr<nsIURL> url(do_QueryInterface(aReferrer)); + if (url) { + nsAutoCString path; + rv = url->GetFilePath(path); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + aResult.Append(path); + rv = NS_MutateURI(url) + .SetQuery(EmptyCString()) + .SetRef(EmptyCString()) + .Finalize(aReferrer); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + break; + } + // No URL, so fall through to truncating the path and any query/ref off + // as well. + } + MOZ_FALLTHROUGH; + default: // (User Pref limited to [0,2]) + case TrimmingPolicy::ePolicySchemeHostPort: + aResult.AppendLiteral("/"); + // This nukes any query/ref present as well in the case of nsStandardURL + rv = NS_MutateURI(aReferrer) + .SetPathQueryRef(EmptyCString()) + .Finalize(aReferrer); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - - aResult.Append(path); - return NS_OK; - } - } - - // Step 6 within https://w3c.github.io/webappsec-referrer-policy/#strip-url - // states that the trailing "/" does not need to get stripped. However, - // GetOriginFromReferrerURI() also removes any trailing "/" hence we have to - // add it back here. - aResult.AppendLiteral("/"); - return NS_OK; -} - -void ReferrerInfo::LogMessageToConsole( - nsIHttpChannel* aChannel, const char* aMsg, - const nsTArray<nsString>& aParams) const { - MOZ_ASSERT(aChannel); - - nsCOMPtr<nsIURI> uri; - nsresult rv = aChannel->GetURI(getter_AddRefs(uri)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; + break; } - uint64_t windowID = 0; - - rv = aChannel->GetTopLevelContentWindowId(&windowID); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - if (!windowID) { - nsCOMPtr<nsILoadGroup> loadGroup; - rv = aChannel->GetLoadGroup(getter_AddRefs(loadGroup)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - if (loadGroup) { - windowID = nsContentUtils::GetInnerWindowID(loadGroup); - } - } - - nsAutoString localizedMsg; - rv = nsContentUtils::FormatLocalizedString( - nsContentUtils::eSECURITY_PROPERTIES, aMsg, aParams, localizedMsg); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - rv = nsContentUtils::ReportToConsoleByWindowID( - localizedMsg, nsIScriptError::infoFlag, NS_LITERAL_CSTRING("Security"), - windowID, uri); - Unused << NS_WARN_IF(NS_FAILED(rv)); + return NS_OK; } - ReferrerInfo::ReferrerInfo() : mOriginalReferrer(nullptr), mPolicy(mozilla::net::RP_Unset), mSendReferrer(true), mInitialized(false), mOverridePolicyByDefault(false), mComputedReferrer(Maybe<nsCString>()) {} @@ -992,34 +902,25 @@ nsresult ReferrerInfo::ComputeReferrer(n if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } referrer = exposableURI; TrimmingPolicy trimmingPolicy = ComputeTrimmingPolicy(aChannel); - nsAutoCString trimmedReferrer; - // We first trim the referrer according to the policy by calling - // 'TrimReferrerWithPolicy' and right after we have to call - // 'LimitReferrerLength' (using the same arguments) because the trimmed - // referrer might exceed the allowed max referrer length. - rv = TrimReferrerWithPolicy(referrer, trimmingPolicy, trimmedReferrer); + nsAutoCString referrerSpec; + rv = TrimReferrerWithPolicy(referrer, trimmingPolicy, referrerSpec); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - rv = LimitReferrerLength(aChannel, referrer, trimmingPolicy, trimmedReferrer); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - // finally, remember the referrer spec. + // finally, remember the referrer URI. mComputedReferrer.reset(); - mComputedReferrer.emplace(trimmedReferrer); + mComputedReferrer.emplace(referrerSpec); return NS_OK; } /* ===== nsISerializable implementation ====== */ NS_IMETHODIMP ReferrerInfo::Read(nsIObjectInputStream* aStream) {
--- a/dom/security/ReferrerInfo.h +++ b/dom/security/ReferrerInfo.h @@ -251,63 +251,22 @@ class ReferrerInfo : public nsIReferrerI friend class mozilla::net::nsHttpChannel; friend class mozilla::dom::Document; /* * Check whether if unset referrer policy is overrided by default or not */ bool IsPolicyOverrided() { return mOverridePolicyByDefault; } /* - * Get origin string from a given valid referrer URI (http, https, ftp) - * - * @aReferrer - the full referrer URI - * @aResult - the resulting aReferrer in string format. - */ - nsresult GetOriginFromReferrerURI(nsIURI* aReferrer, - nsACString& aResult) const; - - /* * Trim a given referrer with a given a trimming policy, */ - nsresult TrimReferrerWithPolicy(nsIURI* aReferrer, + nsresult TrimReferrerWithPolicy(nsCOMPtr<nsIURI>& aReferrer, TrimmingPolicy aTrimmingPolicy, nsACString& aResult) const; - /* - * Limit referrer length using the following ruleset: - * - If the length of referrer URL is over max length, strip down to origin. - * - If the origin is still over max length, remove the referrer entirely. - * - * This function comlements TrimReferrerPolicy and needs to be called right - * after TrimReferrerPolicy. - * - * @aChannel - used to query information needed for logging to the console. - * @aReferrer - the full referrer URI; needs to be identical to aReferrer - * passed to TrimReferrerPolicy. - * @aTrimmingPolicy - represents the trimming policy which was applied to the - * referrer; needs to be identical to aTrimmingPolicy - * passed to TrimReferrerPolicy. - * @aInAndOutTrimmedReferrer - an in and outgoing argument representing the - * referrer value. Please pass the result of - * TrimReferrerWithPolicy as - * aInAndOutTrimmedReferrer which will then be - * reduced to the origin or completely truncated - * in case the referrer value exceeds the length - * limitation. - */ - nsresult LimitReferrerLength(nsIHttpChannel* aChannel, nsIURI* aReferrer, - TrimmingPolicy aTrimmingPolicy, - nsACString& aInAndOutTrimmedReferrer) const; - - /* - * Write message to the error console - */ - void LogMessageToConsole(nsIHttpChannel* aChannel, const char* aMsg, - const nsTArray<nsString>& aParams) const; - nsCOMPtr<nsIURI> mOriginalReferrer; uint32_t mPolicy; // Indicates if the referrer should be sent or not even when it's available // (default is true). bool mSendReferrer;
--- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1600,19 +1600,16 @@ pref("network.http.referer.spoofSource", // false=allow onion referer, true=hide onion referer (use empty referer) pref("network.http.referer.hideOnionSource", false); // 0=full URI, 1=scheme+host+port+path, 2=scheme+host+port pref("network.http.referer.trimmingPolicy", 0); // 0=full URI, 1=scheme+host+port+path, 2=scheme+host+port pref("network.http.referer.XOriginTrimmingPolicy", 0); // 0=always send, 1=send iff base domains match, 2=send iff hosts match pref("network.http.referer.XOriginPolicy", 0); -// The maximum allowed length for a referrer header - 4096 default -// 0 means no limit. -pref("network.http.referer.referrerLengthLimit", 4096); // Include an origin header on non-GET and non-HEAD requests regardless of CORS // 0=never send, 1=send when same-origin only, 2=always send pref("network.http.sendOriginHeader", 0); // Maximum number of consecutive redirects before aborting. pref("network.http.redirection-limit", 20);
--- a/netwerk/test/unit/test_referrer.js +++ b/netwerk/test/unit/test_referrer.js @@ -207,29 +207,16 @@ function run_test() { ); prefs.setIntPref("network.http.referer.XOriginTrimmingPolicy", 0); // test that anchor is lopped off in ordinary case Assert.equal( getTestReferrer(server_uri, referer_uri_2_anchor), referer_uri_2 ); - // test referrer length limitation - // referer_uri's length is 27 and origin's length is 23 - prefs.setIntPref("network.http.referer.referrerLengthLimit", 27); - Assert.equal(getTestReferrer(server_uri, referer_uri), referer_uri); - prefs.setIntPref("network.http.referer.referrerLengthLimit", 26); - Assert.equal(getTestReferrer(server_uri, referer_uri), "http://foo.example.com/"); - prefs.setIntPref("network.http.referer.referrerLengthLimit", 22); - Assert.equal(getTestReferrer(server_uri, referer_uri), null); - prefs.setIntPref("network.http.referer.referrerLengthLimit", 0); - Assert.equal(getTestReferrer(server_uri, referer_uri), referer_uri); - prefs.setIntPref("network.http.referer.referrerLengthLimit", 4096); - Assert.equal(getTestReferrer(server_uri, referer_uri), referer_uri); - // combination test: send spoofed path-only when hosts match var combo_referer_uri = "http://blah.foo.com/path?q=hot"; var dest_uri = "http://blah.foo.com:9999/spoofedpath?q=bad"; prefs.setIntPref("network.http.referer.trimmingPolicy", 1); prefs.setBoolPref("network.http.referer.spoofSource", true); prefs.setIntPref("network.http.referer.XOriginPolicy", 2); Assert.equal( getTestReferrer(dest_uri, combo_referer_uri),