summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/AntiTrackingUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/antitracking/AntiTrackingUtils.cpp')
-rw-r--r--toolkit/components/antitracking/AntiTrackingUtils.cpp135
1 files changed, 96 insertions, 39 deletions
diff --git a/toolkit/components/antitracking/AntiTrackingUtils.cpp b/toolkit/components/antitracking/AntiTrackingUtils.cpp
index 2c530dc3da..d9624237de 100644
--- a/toolkit/components/antitracking/AntiTrackingUtils.cpp
+++ b/toolkit/components/antitracking/AntiTrackingUtils.cpp
@@ -514,6 +514,10 @@ AntiTrackingUtils::GetStoragePermissionStateInParent(nsIChannel* aChannel) {
return nsILoadInfo::NoStoragePermission;
}
+ if (targetPrincipal->IsSystemPrincipal()) {
+ return nsILoadInfo::HasStoragePermission;
+ }
+
nsCOMPtr<nsIURI> trackingURI;
rv = aChannel->GetURI(getter_AddRefs(trackingURI));
if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -821,7 +825,8 @@ void AntiTrackingUtils::ComputeIsThirdPartyToTopWindow(nsIChannel* aChannel) {
// whether the page is third-party, so we use channel result principal
// instead. By doing this, an the resource inherits the principal from
// its parent is considered not a third-party.
- if (NS_IsAboutBlank(uri) || NS_IsAboutSrcdoc(uri)) {
+ if (NS_IsAboutBlank(uri) || NS_IsAboutSrcdoc(uri) ||
+ uri->SchemeIs("blob")) {
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
if (NS_WARN_IF(!ssm)) {
return;
@@ -847,10 +852,36 @@ void AntiTrackingUtils::ComputeIsThirdPartyToTopWindow(nsIChannel* aChannel) {
bool AntiTrackingUtils::IsThirdPartyChannel(nsIChannel* aChannel) {
MOZ_ASSERT(aChannel);
- // We only care whether the channel is 3rd-party with respect to
- // the top-level.
- nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
- return loadInfo->GetIsThirdPartyContextToTopWindow();
+ // We have to handle blob URLs here because they always fail
+ // IsThirdPartyChannel because of how blob URLs are constructed. We just
+ // recompare to their ancestor chain from the loadInfo, bailing if any is
+ // third party.
+ nsAutoCString scheme;
+ nsCOMPtr<nsIURI> channelURI;
+ nsresult rv = aChannel->GetURI(getter_AddRefs(channelURI));
+ if (NS_SUCCEEDED(rv) && channelURI->SchemeIs("blob")) {
+ nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
+ for (const nsCOMPtr<nsIPrincipal>& principal :
+ loadInfo->AncestorPrincipals()) {
+ bool thirdParty = true;
+ rv = loadInfo->PrincipalToInherit()->IsThirdPartyPrincipal(principal,
+ &thirdParty);
+ if (NS_SUCCEEDED(rv) && thirdParty) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ nsCOMPtr<mozIThirdPartyUtil> tpuService =
+ mozilla::components::ThirdPartyUtil::Service();
+ if (!tpuService) {
+ return true;
+ }
+ bool thirdParty = true;
+ rv = tpuService->IsThirdPartyChannel(aChannel, nullptr, &thirdParty);
+ NS_ENSURE_SUCCESS(rv, true);
+ return thirdParty;
}
/* static */
@@ -903,19 +934,29 @@ bool AntiTrackingUtils::IsThirdPartyWindow(nsPIDOMWindowInner* aWindow,
/* static */
bool AntiTrackingUtils::IsThirdPartyDocument(Document* aDocument) {
MOZ_ASSERT(aDocument);
- if (!aDocument->GetChannel()) {
+ nsCOMPtr<mozIThirdPartyUtil> tpuService =
+ mozilla::components::ThirdPartyUtil::Service();
+ if (!tpuService) {
+ return true;
+ }
+ bool thirdParty = true;
+ if (!aDocument->GetChannel() ||
+ aDocument->GetDocumentURI()->SchemeIs("blob")) {
// If we can't get the channel from the document, i.e. initial about:blank
// page, we use the browsingContext of the document to check if it's in the
// third-party context. If the browsing context is still not available, we
// will treat the window as third-party.
+ // We also rely on IsThirdPartyContext for blob documents because the
+ // IsThirdPartyChannel check relies on getting the BaseDomain,
+ // which correctly fails for blobs URIs.
RefPtr<BrowsingContext> bc = aDocument->GetBrowsingContext();
return bc ? IsThirdPartyContext(bc) : true;
}
- // We only care whether the channel is 3rd-party with respect to
- // the top-level.
- nsCOMPtr<nsILoadInfo> loadInfo = aDocument->GetChannel()->LoadInfo();
- return loadInfo->GetIsThirdPartyContextToTopWindow();
+ nsresult rv = tpuService->IsThirdPartyChannel(aDocument->GetChannel(),
+ nullptr, &thirdParty);
+ NS_ENSURE_SUCCESS(rv, true);
+ return thirdParty;
}
/* static */
@@ -923,41 +964,47 @@ bool AntiTrackingUtils::IsThirdPartyContext(BrowsingContext* aBrowsingContext) {
MOZ_ASSERT(aBrowsingContext);
MOZ_ASSERT(aBrowsingContext->IsInProcess());
- if (aBrowsingContext->IsTopContent()) {
- return false;
- }
-
- // If the top browsing context is not in the same process, it's cross-origin.
- if (!aBrowsingContext->Top()->IsInProcess()) {
- return true;
- }
-
+ // iframes with SANDBOX_ORIGIN are always third-party contexts
+ // because they are a unique origin
nsIDocShell* docShell = aBrowsingContext->GetDocShell();
if (!docShell) {
return true;
}
Document* doc = docShell->GetExtantDocument();
- if (!doc) {
+ if (!doc || doc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
return true;
}
nsIPrincipal* principal = doc->NodePrincipal();
- nsIDocShell* topDocShell = aBrowsingContext->Top()->GetDocShell();
- if (!topDocShell) {
- return true;
- }
- Document* topDoc = topDocShell->GetDocument();
- if (!topDoc) {
- return true;
- }
- nsIPrincipal* topPrincipal = topDoc->NodePrincipal();
+ BrowsingContext* traversingParent = aBrowsingContext->GetParent();
+ while (traversingParent) {
+ // If the parent browsing context is not in the same process, it's
+ // cross-origin.
+ if (!traversingParent->IsInProcess()) {
+ return true;
+ }
- auto* topBasePrin = BasePrincipal::Cast(topPrincipal);
- bool isThirdParty = true;
+ nsIDocShell* parentDocShell = traversingParent->GetDocShell();
+ if (!parentDocShell) {
+ return true;
+ }
+ Document* parentDoc = parentDocShell->GetDocument();
+ if (!parentDoc || parentDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
+ return true;
+ }
+ nsIPrincipal* parentPrincipal = parentDoc->NodePrincipal();
+
+ auto* parentBasePrin = BasePrincipal::Cast(parentPrincipal);
+ bool isThirdParty = true;
- topBasePrin->IsThirdPartyPrincipal(principal, &isThirdParty);
+ parentBasePrin->IsThirdPartyPrincipal(principal, &isThirdParty);
+ if (isThirdParty) {
+ return true;
+ }
- return isThirdParty;
+ traversingParent = traversingParent->GetParent();
+ }
+ return false;
}
/* static */
@@ -1005,6 +1052,18 @@ void AntiTrackingUtils::UpdateAntiTrackingInfoForChannel(nsIChannel* aChannel) {
->MarkOverriddenFingerprintingSettingsAsSet();
#endif
+ ExtContentPolicyType contentType = loadInfo->GetExternalContentPolicyType();
+ if (contentType == ExtContentPolicy::TYPE_DOCUMENT ||
+ contentType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
+ nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
+ Unused << loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
+ // For subdocuments, the channel's partition key is that of the parent
+ // document. This document may have a different partition key, particularly
+ // one without the same-site bit.
+ net::CookieJarSettings::Cast(cookieJarSettings)
+ ->UpdatePartitionKeyForDocumentLoadedByChannel(aChannel);
+ }
+
// We only update the IsOnContentBlockingAllowList flag and the partition key
// for the top-level http channel.
//
@@ -1015,17 +1074,15 @@ void AntiTrackingUtils::UpdateAntiTrackingInfoForChannel(nsIChannel* aChannel) {
// The partition key is computed based on the site, so it's no point to set it
// for channels other than http channels.
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
- if (!httpChannel || loadInfo->GetExternalContentPolicyType() !=
- ExtContentPolicy::TYPE_DOCUMENT) {
+ if (!httpChannel || contentType != ExtContentPolicy::TYPE_DOCUMENT) {
return;
}
- nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
- Unused << loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
-
// Update the IsOnContentBlockingAllowList flag in the CookieJarSettings
// if this is a top level loading. For sub-document loading, this flag
// would inherit from the parent.
+ nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
+ Unused << loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
net::CookieJarSettings::Cast(cookieJarSettings)
->UpdateIsOnContentBlockingAllowList(aChannel);
@@ -1033,7 +1090,7 @@ void AntiTrackingUtils::UpdateAntiTrackingInfoForChannel(nsIChannel* aChannel) {
// propagated to non-top level loads via CookieJarSetting.
nsCOMPtr<nsIURI> uri;
Unused << aChannel->GetURI(getter_AddRefs(uri));
- net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri);
+ net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri, false);
// Generate the fingerprinting randomization key for top-level loads. The key
// will automatically be propagated to sub loads.