mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1770498: Create ShouldRFP(nsILoadInfo) and make ShouldRFP(nsIPrincipal) explicitly dangerous r=timhuang
- Move ShouldRFP(char*), ShouldRFP(docshell), ShouldRFP(Document) below some utility code. - Now that we know we should check the CookieJarSettings, using ShouldRFP(nsIPrincipal) is dangerous. We mark it as dangerous and annotate the existing uses of it. - At the same time, an nsILoadInfo has the CookieJarSettings we want to check, so create a ShouldRFP(nsILoadInfo) that checks it and cascades to the (marked-dangerous-but-not-dangerous-for- this-call) principal function. - We also correct a situation where WorkerLoadInfo does not initialize the shouldRFP member. Differential Revision: https://phabricator.services.mozilla.com/D150591
This commit is contained in:
parent
61152c85e9
commit
b732796900
@ -2132,37 +2132,6 @@ bool nsContentUtils::ShouldResistFingerprinting(
|
||||
|
||||
// Newer Should RFP Functions ----------------------------------
|
||||
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldResistFingerprinting(const char* aJustification) {
|
||||
// See comment in header file for information about usage
|
||||
return ShouldResistFingerprinting();
|
||||
}
|
||||
|
||||
bool nsContentUtils::ShouldResistFingerprinting(nsIDocShell* aDocShell) {
|
||||
if (!aDocShell) {
|
||||
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
|
||||
("Called nsContentUtils::ShouldResistFingerprinting(const "
|
||||
"nsIDocShell* aDocShell) with NULL docshell"));
|
||||
return ShouldResistFingerprinting();
|
||||
}
|
||||
return ShouldResistFingerprinting(aDocShell->GetDocument());
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldResistFingerprinting(const Document* aDoc) {
|
||||
if (!aDoc) {
|
||||
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
|
||||
("Called nsContentUtils::ShouldResistFingerprinting(const "
|
||||
"Document* aDoc) with NULL document"));
|
||||
return ShouldResistFingerprinting();
|
||||
}
|
||||
bool isChrome = nsContentUtils::IsChromeDoc(aDoc);
|
||||
if (isChrome) {
|
||||
return false;
|
||||
}
|
||||
return ShouldResistFingerprinting(aDoc->GetChannel());
|
||||
}
|
||||
|
||||
inline void LogDomainAndPrefList(const char* exemptedDomainsPrefName,
|
||||
nsAutoCString& url, bool isExemptDomain) {
|
||||
nsAutoCString list;
|
||||
@ -2180,6 +2149,41 @@ const unsigned int sSpecificDomainsExemptMask = 0x04;
|
||||
const char* kExemptedDomainsPrefName =
|
||||
"privacy.resistFingerprinting.exemptedDomains";
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldResistFingerprinting(const char* aJustification) {
|
||||
// See comment in header file for information about usage
|
||||
return ShouldResistFingerprinting();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
bool nsContentUtils::ShouldResistFingerprinting(nsIDocShell* aDocShell) {
|
||||
if (!aDocShell) {
|
||||
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
|
||||
("Called nsContentUtils::ShouldResistFingerprinting(const "
|
||||
"nsIDocShell* aDocShell) with NULL docshell"));
|
||||
return ShouldResistFingerprinting();
|
||||
}
|
||||
return ShouldResistFingerprinting(aDocShell->GetDocument());
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldResistFingerprinting(const Document* aDoc) {
|
||||
if (!aDoc) {
|
||||
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
|
||||
("Called nsContentUtils::ShouldResistFingerprinting(const "
|
||||
"Document* aDoc) with NULL document"));
|
||||
return ShouldResistFingerprinting();
|
||||
}
|
||||
bool isChrome = nsContentUtils::IsChromeDoc(aDoc);
|
||||
if (isChrome) {
|
||||
return false;
|
||||
}
|
||||
return ShouldResistFingerprinting(aDoc->GetChannel());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldResistFingerprinting(nsIChannel* aChannel) {
|
||||
if (!ShouldResistFingerprinting("Legacy quick-check")) {
|
||||
@ -2201,30 +2205,34 @@ bool nsContentUtils::ShouldResistFingerprinting(nsIChannel* aChannel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the loadinfo's CookieJarSettings says that we _should_ resist
|
||||
// fingerprinting we can always believe it. (This is the (*) rule from
|
||||
// CookieJarSettings.h)
|
||||
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
|
||||
nsresult rv =
|
||||
loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
|
||||
("Called nsContentUtils::ShouldResistFingerprinting(nsIChannel* "
|
||||
"aChannel) but the channel's loadinfo's CookieJarSettings "
|
||||
"couldn't be retrieved: %d",
|
||||
rv));
|
||||
return true;
|
||||
}
|
||||
if (cookieJarSettings->GetShouldResistFingerprinting()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Document types have no loading principal. Subdocument types do have a
|
||||
// loading principal, but it is the loading principal of the parent document;
|
||||
// not the subdocument.
|
||||
auto contentType = loadInfo->GetExternalContentPolicyType();
|
||||
if (contentType == ExtContentPolicy::TYPE_DOCUMENT ||
|
||||
contentType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
|
||||
// This cookie jar check is relevant to both document and non-document
|
||||
// cases. but it will be performed inside the ShouldRFP(nsILoadInfo) as
|
||||
// well, so we put into this conditional to avoid doing it twice in that
|
||||
// case.
|
||||
|
||||
// If the loadinfo's CookieJarSettings says that we _should_ resist
|
||||
// fingerprinting we can always believe it. (This is the (*) rule from
|
||||
// CookieJarSettings.h)
|
||||
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
|
||||
nsresult rv =
|
||||
loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
|
||||
("Called nsContentUtils::ShouldResistFingerprinting(nsIChannel* "
|
||||
"aChannel) but the channel's loadinfo's CookieJarSettings "
|
||||
"couldn't be retrieved"));
|
||||
return true;
|
||||
}
|
||||
if (cookieJarSettings->GetShouldResistFingerprinting()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> channelURI;
|
||||
rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
|
||||
MOZ_ASSERT(
|
||||
@ -2265,11 +2273,10 @@ bool nsContentUtils::ShouldResistFingerprinting(nsIChannel* aChannel) {
|
||||
}
|
||||
|
||||
// Case 2: Subresource Load
|
||||
MOZ_ASSERT(BasePrincipal::Cast(loadInfo->GetLoadingPrincipal())
|
||||
->OriginAttributesRef() == loadInfo->GetOriginAttributes());
|
||||
return ShouldResistFingerprinting(loadInfo->GetLoadingPrincipal());
|
||||
return ShouldResistFingerprinting(loadInfo);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldResistFingerprinting_dangerous(
|
||||
nsIURI* aURI, const mozilla::OriginAttributes& aOriginAttributes,
|
||||
@ -2318,15 +2325,58 @@ bool nsContentUtils::ShouldResistFingerprinting_dangerous(
|
||||
return !isExemptDomain;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldResistFingerprinting(nsIPrincipal* aPrincipal) {
|
||||
bool nsContentUtils::ShouldResistFingerprinting(nsILoadInfo* aLoadInfo) {
|
||||
MOZ_ASSERT(aLoadInfo->GetExternalContentPolicyType() != ExtContentPolicy::TYPE_DOCUMENT &&
|
||||
aLoadInfo->GetExternalContentPolicyType() != ExtContentPolicy::TYPE_SUBDOCUMENT);
|
||||
|
||||
if (!ShouldResistFingerprinting("Legacy quick-check")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the loadinfo's CookieJarSettings says that we _should_ resist
|
||||
// fingerprinting we can always believe it. (This is the (*) rule from
|
||||
// CookieJarSettings.h)
|
||||
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
|
||||
nsresult rv =
|
||||
aLoadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
|
||||
("Called nsContentUtils::ShouldResistFingerprinting(nsIChannel* "
|
||||
"aChannel) but the channel's loadinfo's CookieJarSettings "
|
||||
"couldn't be retrieved"));
|
||||
return true;
|
||||
}
|
||||
if (cookieJarSettings->GetShouldResistFingerprinting()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Because this function is only used for subresource loads, this
|
||||
// will check the parent's principal
|
||||
nsIPrincipal* principal = aLoadInfo->GetLoadingPrincipal();
|
||||
MOZ_ASSERT(BasePrincipal::Cast(principal)->OriginAttributesRef() ==
|
||||
aLoadInfo->GetOriginAttributes());
|
||||
return ShouldResistFingerprinting_dangerous(principal, "Internal Call");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/* static */
|
||||
bool nsContentUtils::ShouldResistFingerprinting_dangerous(
|
||||
nsIPrincipal* aPrincipal, const char* aJustification) {
|
||||
if (!ShouldResistFingerprinting("Legacy quick-check")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aPrincipal) {
|
||||
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
|
||||
("Called nsContentUtils::ShouldResistFingerprinting(nsILoadInfo* "
|
||||
"aChannel) but the loadinfo's loadingprincipal was NULL"));
|
||||
return true;
|
||||
}
|
||||
|
||||
auto originAttributes =
|
||||
BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
|
||||
|
||||
if (StaticPrefs::privacy_resistFingerprinting_testGranularityMask() &
|
||||
sNonPBMExemptMask) {
|
||||
// if non-PBM exempt mask is true, exempt non-PBM channels.
|
||||
@ -2391,6 +2441,7 @@ bool nsContentUtils::ShouldResistFingerprinting(nsIPrincipal* aPrincipal) {
|
||||
return !isExemptDomain;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/* static */
|
||||
void nsContentUtils::CalcRoundedWindowSizeForResistingFingerprinting(
|
||||
int32_t aChromeWidth, int32_t aChromeHeight, int32_t aScreenWidth,
|
||||
|
@ -352,17 +352,19 @@ class nsContentUtils {
|
||||
// These functions are the new, nuanced functions
|
||||
static bool ShouldResistFingerprinting(const Document* aDoc);
|
||||
static bool ShouldResistFingerprinting(nsIChannel* aChannel);
|
||||
// This function is labeled as dangerous because it will do the wrong thing
|
||||
// in _most_ cases. It should only be used if you don't have a fully
|
||||
static bool ShouldResistFingerprinting(nsILoadInfo* aPrincipal);
|
||||
// These functions are labeled as dangerous because they will do the wrong
|
||||
// thing in _most_ cases. They should only be used if you don't have a fully
|
||||
// constructed LoadInfo or Document.
|
||||
// A constant string used as justification is required when calling this,
|
||||
// A constant string used as justification is required when calling them,
|
||||
// it should explain why a Document, Channel, LoadInfo, or CookieJarSettings
|
||||
// does not exist in this context.
|
||||
// (see below for more on justification strings.)
|
||||
static bool ShouldResistFingerprinting_dangerous(
|
||||
nsIURI* aURI, const mozilla::OriginAttributes& aOriginAttributes,
|
||||
const char* aJustification);
|
||||
static bool ShouldResistFingerprinting(nsIPrincipal* aPrincipal);
|
||||
static bool ShouldResistFingerprinting_dangerous(nsIPrincipal* aPrincipal,
|
||||
const char* aJustification);
|
||||
|
||||
/**
|
||||
* Implement a RFP function that only checks the pref, and does not take
|
||||
|
@ -249,7 +249,12 @@ nsresult ServiceWorkerPrivateImpl::Initialize() {
|
||||
/* referrerInfo */ nullptr,
|
||||
|
||||
storageAccess, isThirdPartyContextToTopWindow,
|
||||
nsContentUtils::ShouldResistFingerprinting(principal),
|
||||
nsContentUtils::ShouldResistFingerprinting_dangerous(
|
||||
principal,
|
||||
"Service Workers exist outside a Document or Channel; as a property "
|
||||
"of the domain (and origin attributes). We don't have a "
|
||||
"CookieJarSettings to perform the nested check, but we can rely on"
|
||||
"the FPI/dFPI partition key check."),
|
||||
// Origin trials are associated to a window, so it doesn't make sense on
|
||||
// service workers.
|
||||
OriginTrials(), std::move(serviceWorkerData), regInfo->AgentClusterId(),
|
||||
|
@ -1347,7 +1347,12 @@ nsresult nsWebBrowserPersist::SaveURIInternal(
|
||||
// loading principal in the download channel, so we treat it as a loading
|
||||
// principal also.
|
||||
bool shouldResistFingerprinting =
|
||||
nsContentUtils::ShouldResistFingerprinting(aTriggeringPrincipal);
|
||||
nsContentUtils::ShouldResistFingerprinting_dangerous(
|
||||
aTriggeringPrincipal,
|
||||
"We are creating a new CookieJar Settings, so none exists "
|
||||
"currently. Although the variable is called 'triggering principal',"
|
||||
"it is used as the loading principal in the download channel, so we"
|
||||
"treat it as a loading principal also.");
|
||||
cookieJarSettings =
|
||||
aIsPrivate
|
||||
? net::CookieJarSettings::Create(net::CookieJarSettings::ePrivate,
|
||||
|
@ -2925,6 +2925,10 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
|
||||
loadInfo.mHasStorageAccessPermissionGranted = false;
|
||||
loadInfo.mCookieJarSettings =
|
||||
mozilla::net::CookieJarSettings::Create(loadInfo.mLoadingPrincipal);
|
||||
loadInfo.mShouldResistFingerprinting =
|
||||
nsContentUtils::ShouldResistFingerprinting_dangerous(
|
||||
loadInfo.mLoadingPrincipal,
|
||||
"Unusual situation - we have no document or CookieJarSettings");
|
||||
MOZ_ASSERT(loadInfo.mCookieJarSettings);
|
||||
|
||||
loadInfo.mOriginAttributes = OriginAttributes();
|
||||
|
@ -1042,7 +1042,9 @@ LoadInfo::GetCookieJarSettings(nsICookieJarSettings** aCookieJarSettings) {
|
||||
nsCOMPtr<nsIPrincipal> loadingPrincipal;
|
||||
Unused << this->GetLoadingPrincipal(getter_AddRefs(loadingPrincipal));
|
||||
bool shouldResistFingerprinting =
|
||||
nsContentUtils::ShouldResistFingerprinting(loadingPrincipal);
|
||||
nsContentUtils::ShouldResistFingerprinting_dangerous(
|
||||
loadingPrincipal,
|
||||
"CookieJarSettings can't exist yet, we're creating it");
|
||||
mCookieJarSettings = CreateCookieJarSettings(
|
||||
mInternalContentPolicyType, isPrivate, shouldResistFingerprinting);
|
||||
}
|
||||
|
@ -129,7 +129,8 @@ already_AddRefed<nsICookieJarSettings> CookieJarSettings::Create(
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
bool shouldResistFingerprinting =
|
||||
nsContentUtils::ShouldResistFingerprinting(aPrincipal);
|
||||
nsContentUtils::ShouldResistFingerprinting_dangerous(
|
||||
aPrincipal, "We are constructing CookieJarSettings here.");
|
||||
|
||||
if (aPrincipal && aPrincipal->OriginAttributesRef().mPrivateBrowsingId > 0) {
|
||||
return Create(ePrivate, shouldResistFingerprinting);
|
||||
|
Loading…
Reference in New Issue
Block a user