Bug 1770498: Use the CookieJarSetting's ShouldRFP Member in nsContentUtils::ShouldRFP r=timhuang

Now that the ShouldRFP member is correctly populated (we hope)
in CookieJarSettings, we can use it in our ShouldRFP methods.

There are two general scenarios:
  An exempted domain frames a non-exempted domain.
     The inner frame should be non-exempted.
  A non-exempted domain frames an exempted domain
     The inner frame should be non-exempted.

In the first scenario, CookieJarSettings.shouldRFP member
will be false (exempted.)  We clearly cannot blindly rely
on the member, it would be wrong here.

In the second scenario, CookieJarSettings.shouldRFP member
will be true (non-exempted). This is the scenario we really
need CookieJarSettings for.

----

We take the opportunity to add an additional check for the
'exempted domain framed by a non-exempted domain' scenario.
This additional check takes advantage of the first party
isolation key (for FPI) or partition key (for dFPI).

Differential Revision: https://phabricator.services.mozilla.com/D150589
This commit is contained in:
Tom Ritter 2022-07-15 20:39:19 +00:00
parent 1c40624193
commit 700f6f1322

View File

@ -2194,6 +2194,30 @@ bool nsContentUtils::ShouldResistFingerprinting(nsIChannel* aChannel) {
}
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
if (!loadInfo) {
MOZ_LOG(nsContentUtils::ResistFingerprintingLog(), LogLevel::Info,
("Called nsContentUtils::ShouldResistFingerprinting(nsIChannel* "
"aChannel) but the channel's loadinfo was NULL"));
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;
@ -2202,7 +2226,7 @@ bool nsContentUtils::ShouldResistFingerprinting(nsIChannel* aChannel) {
if (contentType == ExtContentPolicy::TYPE_DOCUMENT ||
contentType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
nsCOMPtr<nsIURI> channelURI;
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
MOZ_ASSERT(
NS_SUCCEEDED(rv),
"Failed to get URI in "
@ -2337,6 +2361,33 @@ bool nsContentUtils::ShouldResistFingerprinting(nsIPrincipal* aPrincipal) {
}
}
// If we've gotten here we have (probably) passed the CookieJarSettings
// check that would tell us that if we _are_ a subdocument, then we are on
// an exempted top-level domain and we should see if we ourselves are
// exempted. But we may have gotten here because we directly called the
// _dangerous function and we haven't done that check, but we _were_
// instatiated from a state where we could have been partitioned.
// So perform this last-ditch check for that scenario.
// We arbitrarily use https as the scheme, but it doesn't matter.
nsCOMPtr<nsIURI> uri;
nsresult rv;
if (isExemptDomain && StaticPrefs::privacy_firstparty_isolate() &&
!originAttributes.mFirstPartyDomain.IsEmpty()) {
rv = NS_NewURI(getter_AddRefs(uri),
u"https://"_ns + originAttributes.mFirstPartyDomain);
if (!NS_FAILED(rv)) {
isExemptDomain =
nsContentUtils::IsURIInPrefList(uri, kExemptedDomainsPrefName);
}
} else if (isExemptDomain && !originAttributes.mPartitionKey.IsEmpty()) {
rv = NS_NewURI(getter_AddRefs(uri),
u"https://"_ns + originAttributes.mPartitionKey);
if (!NS_FAILED(rv)) {
isExemptDomain =
nsContentUtils::IsURIInPrefList(uri, kExemptedDomainsPrefName);
}
}
return !isExemptDomain;
}