diff --git a/toolkit/components/antitracking/AntiTrackingCommon.cpp b/toolkit/components/antitracking/AntiTrackingCommon.cpp index 3143a2914b6d..9a1829edcbd3 100644 --- a/toolkit/components/antitracking/AntiTrackingCommon.cpp +++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp @@ -156,57 +156,51 @@ void CreatePermissionKey(const nsCString& aTrackingOrigin, // This internal method returns ACCESS_DENY if the access is denied, // ACCESS_DEFAULT if unknown, some other access code if granted. -nsCookieAccess CheckCookiePermissionForPrincipal(nsIPrincipal* aPrincipal) { - nsCookieAccess access = nsICookiePermission::ACCESS_DEFAULT; +uint32_t CheckCookiePermissionForPrincipal(nsICookieSettings* aCookieSettings, + nsIPrincipal* aPrincipal) { + MOZ_ASSERT(aCookieSettings); + MOZ_ASSERT(aPrincipal); + + uint32_t cookiePermission = nsICookiePermission::ACCESS_DEFAULT; if (!aPrincipal->GetIsCodebasePrincipal()) { - return access; + return cookiePermission; } - nsCOMPtr cps = nsCookiePermission::GetOrCreate(); - - nsresult rv = cps->CanAccess(aPrincipal, &access); + nsresult rv = + aCookieSettings->CookiePermission(aPrincipal, &cookiePermission); if (NS_WARN_IF(NS_FAILED(rv))) { return nsICookiePermission::ACCESS_DEFAULT; } // If we have a custom cookie permission, let's use it. - return access; + return cookiePermission; } -// This internal method returns ACCESS_DENY if the access is denied, -// ACCESS_DEFAULT if unknown, some other access code if granted. -nsCookieAccess CheckCookiePermissionForURI(nsIURI* aURI) { - nsCookieAccess access = nsICookiePermission::ACCESS_DEFAULT; +int32_t CookiesBehavior(Document* aTopLevelDocument, + Document* a3rdPartyDocument) { + MOZ_ASSERT(aTopLevelDocument); + MOZ_ASSERT(a3rdPartyDocument); - nsCOMPtr cps = nsCookiePermission::GetOrCreate(); - - nsresult rv = cps->CanAccessURI(aURI, &access); - if (NS_WARN_IF(NS_FAILED(rv))) { - return nsICookiePermission::ACCESS_DEFAULT; - } - - // If we have a custom cookie permission, let's use it. - return access; -} - -int32_t CookiesBehavior(nsIPrincipal* aTopLevelPrincipal, - nsIPrincipal* a3rdPartyPrincipal) { // WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior // (See Bug 1406675 for rationale). - if (BasePrincipal::Cast(aTopLevelPrincipal)->AddonPolicy()) { + if (BasePrincipal::Cast(aTopLevelDocument->NodePrincipal())->AddonPolicy()) { return nsICookieService::BEHAVIOR_ACCEPT; } - if (a3rdPartyPrincipal && - BasePrincipal::Cast(a3rdPartyPrincipal)->AddonPolicy()) { + if (BasePrincipal::Cast(a3rdPartyDocument->NodePrincipal())->AddonPolicy()) { return nsICookieService::BEHAVIOR_ACCEPT; } - return StaticPrefs::network_cookie_cookieBehavior(); + return a3rdPartyDocument->CookieSettings()->GetCookieBehavior(); } -int32_t CookiesBehavior(nsIPrincipal* aTopLevelPrincipal, +int32_t CookiesBehavior(nsILoadInfo* aLoadInfo, + nsIPrincipal* aTopLevelPrincipal, nsIURI* a3rdPartyURI) { + MOZ_ASSERT(aLoadInfo); + MOZ_ASSERT(aTopLevelPrincipal); + MOZ_ASSERT(a3rdPartyURI); + // WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior // (See Bug 1406675 for rationale). if (BasePrincipal::Cast(aTopLevelPrincipal)->AddonPolicy()) { @@ -215,13 +209,30 @@ int32_t CookiesBehavior(nsIPrincipal* aTopLevelPrincipal, // This is semantically equivalent to the principal having a AddonPolicy(). bool is3rdPartyMozExt = false; - if (a3rdPartyURI && - NS_SUCCEEDED( + if (NS_SUCCEEDED( a3rdPartyURI->SchemeIs("moz-extension", &is3rdPartyMozExt)) && is3rdPartyMozExt) { return nsICookieService::BEHAVIOR_ACCEPT; } + nsCOMPtr cookieSettings; + nsresult rv = aLoadInfo->GetCookieSettings(getter_AddRefs(cookieSettings)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nsICookieService::BEHAVIOR_REJECT; + } + + return cookieSettings->GetCookieBehavior(); +} + +int32_t CookiesBehavior(nsIPrincipal* aPrincipal) { + MOZ_ASSERT(aPrincipal); + + // WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior + // (See Bug 1406675 for rationale). + if (BasePrincipal::Cast(aPrincipal)->AddonPolicy()) { + return nsICookieService::BEHAVIOR_ACCEPT; + } + return StaticPrefs::network_cookie_cookieBehavior(); } @@ -1066,31 +1077,50 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( aURI); nsGlobalWindowInner* innerWindow = nsGlobalWindowInner::Cast(aWindow); - nsIPrincipal* windowPrincipal = innerWindow->GetPrincipal(); - if (!windowPrincipal) { - LOG(("Our window has no principal")); + Document* document = innerWindow->GetExtantDoc(); + if (!document) { + LOG(("Our window has no document")); return false; } - nsIPrincipal* toplevelPrincipal = innerWindow->GetTopLevelPrincipal(); - if (!toplevelPrincipal) { - // We are already the top-level principal. Let's use the window's principal. - LOG( - ("Our inner window lacks a top-level principal, use the window's " - "principal instead")); - toplevelPrincipal = windowPrincipal; + nsGlobalWindowOuter* outerWindow = + nsGlobalWindowOuter::Cast(aWindow->GetOuterWindow()); + if (!outerWindow) { + LOG(("Our window has no outer window")); + return false; } - MOZ_ASSERT(toplevelPrincipal); + nsCOMPtr topOuterWindow = outerWindow->GetTop(); + nsGlobalWindowOuter* topWindow = nsGlobalWindowOuter::Cast(topOuterWindow); + if (NS_WARN_IF(!topWindow)) { + LOG(("No top outer window")); + return false; + } - nsCookieAccess access = CheckCookiePermissionForPrincipal(toplevelPrincipal); - if (access != nsICookiePermission::ACCESS_DEFAULT) { + nsPIDOMWindowInner* topInnerWindow = topWindow->GetCurrentInnerWindow(); + if (NS_WARN_IF(!topInnerWindow)) { + LOG(("No top inner window.")); + return false; + } + + Document* toplevelDocument = topInnerWindow->GetExtantDoc(); + if (!toplevelDocument) { + LOG(("No top level document.")); + return false; + } + + MOZ_ASSERT(toplevelDocument); + + uint32_t cookiePermission = CheckCookiePermissionForPrincipal( + toplevelDocument->CookieSettings(), toplevelDocument->NodePrincipal()); + if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d) for top-level window's principal, returning %s", - int(access), - access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); - if (access != nsICookiePermission::ACCESS_DENY) { + int(cookiePermission), + cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" + : "failure")); + if (cookiePermission != nsICookiePermission::ACCESS_DENY) { return true; } @@ -1099,14 +1129,16 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - access = CheckCookiePermissionForPrincipal(windowPrincipal); - if (access != nsICookiePermission::ACCESS_DEFAULT) { + cookiePermission = CheckCookiePermissionForPrincipal( + toplevelDocument->CookieSettings(), document->NodePrincipal()); + if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d) for window's principal, returning %s", - int(access), - access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); - if (access != nsICookiePermission::ACCESS_DENY) { + int(cookiePermission), + cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" + : "failure")); + if (cookiePermission != nsICookiePermission::ACCESS_DENY) { return true; } @@ -1115,7 +1147,7 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - int32_t behavior = CookiesBehavior(toplevelPrincipal, windowPrincipal); + int32_t behavior = CookiesBehavior(toplevelDocument, document); if (behavior == nsICookieService::BEHAVIOR_ACCEPT) { LOG(("The cookie behavior pref mandates accepting all cookies!")); return true; @@ -1194,26 +1226,6 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - nsGlobalWindowOuter* outerWindow = - nsGlobalWindowOuter::Cast(aWindow->GetOuterWindow()); - if (NS_WARN_IF(!outerWindow)) { - LOG(("No outer window.")); - return false; - } - - nsCOMPtr topOuterWindow = outerWindow->GetTop(); - nsGlobalWindowOuter* topWindow = nsGlobalWindowOuter::Cast(topOuterWindow); - if (NS_WARN_IF(!topWindow)) { - LOG(("No top outer window.")); - return false; - } - - nsPIDOMWindowInner* topInnerWindow = topWindow->GetCurrentInnerWindow(); - if (NS_WARN_IF(!topInnerWindow)) { - LOG(("No top inner window.")); - return false; - } - nsAutoCString type; CreatePermissionKey(trackingOrigin, grantedOrigin, type); @@ -1229,8 +1241,7 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( } uint32_t result = 0; - rv = permManager->TestPermissionWithoutDefaultsFromPrincipal(parentPrincipal, - type, &result); + rv = permManager->TestPermissionFromPrincipal(parentPrincipal, type, &result); if (NS_WARN_IF(NS_FAILED(rv))) { LOG(("Failed to test the permission")); return false; @@ -1261,6 +1272,10 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( aRejectedReason = &rejectedReason; } + nsIScriptSecurityManager* ssm = + nsScriptSecurityManager::GetScriptSecurityManager(); + MOZ_ASSERT(ssm); + nsCOMPtr channelURI; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI)); if (NS_FAILED(rv)) { @@ -1296,8 +1311,6 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( bool isDocument = false; rv = aChannel->GetIsMainDocumentChannel(&isDocument); if (NS_SUCCEEDED(rv) && isDocument) { - nsIScriptSecurityManager* ssm = - nsScriptSecurityManager::GetScriptSecurityManager(); rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(toplevelPrincipal)); if (NS_SUCCEEDED(rv)) { @@ -1325,14 +1338,25 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - nsCookieAccess access = CheckCookiePermissionForPrincipal(toplevelPrincipal); - if (access != nsICookiePermission::ACCESS_DEFAULT) { + nsCOMPtr cookieSettings; + rv = loadInfo->GetCookieSettings(getter_AddRefs(cookieSettings)); + if (NS_WARN_IF(NS_FAILED(rv))) { + LOG( + ("Failed to get the cookie settings from the loadinfo, bail out " + "early")); + return true; + } + + uint32_t cookiePermission = + CheckCookiePermissionForPrincipal(cookieSettings, toplevelPrincipal); + if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d) for top-level window's principal, returning %s", - int(access), - access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); - if (access != nsICookiePermission::ACCESS_DENY) { + int(cookiePermission), + cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" + : "failure")); + if (cookiePermission != nsICookiePermission::ACCESS_DENY) { return true; } @@ -1341,19 +1365,24 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - if (NS_WARN_IF(NS_FAILED(rv) || !channelURI)) { + nsCOMPtr channelPrincipal; + rv = ssm->GetChannelResultPrincipal(aChannel, + getter_AddRefs(channelPrincipal)); + if (NS_WARN_IF(NS_FAILED(rv))) { LOG(("No channel principal, bail out early")); return false; } - access = CheckCookiePermissionForURI(channelURI); - if (access != nsICookiePermission::ACCESS_DEFAULT) { + cookiePermission = + CheckCookiePermissionForPrincipal(cookieSettings, channelPrincipal); + if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d) for channel's principal, returning %s", - int(access), - access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); - if (access != nsICookiePermission::ACCESS_DENY) { + int(cookiePermission), + cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" + : "failure")); + if (cookiePermission != nsICookiePermission::ACCESS_DENY) { return true; } @@ -1362,7 +1391,12 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( return false; } - int32_t behavior = CookiesBehavior(toplevelPrincipal, channelURI); + if (!channelURI) { + LOG(("No channel uri, bail out early")); + return false; + } + + int32_t behavior = CookiesBehavior(loadInfo, toplevelPrincipal, channelURI); if (behavior == nsICookieService::BEHAVIOR_ACCEPT) { LOG(("The cookie behavior pref mandates accepting all cookies!")); return true; @@ -1497,13 +1531,17 @@ bool AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor( nsIPrincipal* aPrincipal) { MOZ_ASSERT(aPrincipal); - nsCookieAccess access = CheckCookiePermissionForPrincipal(aPrincipal); + nsCookieAccess access = nsICookiePermission::ACCESS_DEFAULT; + if (aPrincipal->GetIsCodebasePrincipal()) { + nsCOMPtr cps = nsCookiePermission::GetOrCreate(); + Unused << NS_WARN_IF(NS_FAILED(cps->CanAccess(aPrincipal, &access))); + } + if (access != nsICookiePermission::ACCESS_DEFAULT) { return access != nsICookiePermission::ACCESS_DENY; } - int32_t behavior = - CookiesBehavior(aPrincipal, static_cast(nullptr)); + int32_t behavior = CookiesBehavior(aPrincipal); return behavior != nsICookieService::BEHAVIOR_REJECT; } @@ -1518,7 +1556,14 @@ bool AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor( aFirstPartyWindow, _spec), aURI); - if (StaticPrefs::network_cookie_cookieBehavior() != + Document* parentDocument = + nsGlobalWindowInner::Cast(aFirstPartyWindow)->GetExtantDoc(); + if (NS_WARN_IF(!parentDocument)) { + LOG(("Failed to get the first party window's document")); + return false; + } + + if (parentDocument->CookieSettings()->GetCookieBehavior() != nsICookieService::BEHAVIOR_REJECT_TRACKER) { LOG(("Disabled by the pref (%d), bail out early", StaticPrefs::network_cookie_cookieBehavior())); @@ -1535,21 +1580,16 @@ bool AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor( return true; } - nsCOMPtr parentPrincipal = - nsGlobalWindowInner::Cast(aFirstPartyWindow)->GetPrincipal(); - if (NS_WARN_IF(!parentPrincipal)) { - LOG(("Failed to get the first party window's principal")); - return false; - } - - nsCookieAccess access = CheckCookiePermissionForPrincipal(parentPrincipal); - if (access != nsICookiePermission::ACCESS_DEFAULT) { + uint32_t cookiePermission = CheckCookiePermissionForPrincipal( + parentDocument->CookieSettings(), parentDocument->NodePrincipal()); + if (cookiePermission != nsICookiePermission::ACCESS_DEFAULT) { LOG( ("CheckCookiePermissionForPrincipal() returned a non-default access " "code (%d), returning %s", - int(access), - access != nsICookiePermission::ACCESS_DENY ? "success" : "failure")); - return access != nsICookiePermission::ACCESS_DENY; + int(cookiePermission), + cookiePermission != nsICookiePermission::ACCESS_DENY ? "success" + : "failure")); + return cookiePermission != nsICookiePermission::ACCESS_DENY; } nsAutoCString origin; @@ -1569,8 +1609,8 @@ bool AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor( } uint32_t result = 0; - rv = permManager->TestPermissionWithoutDefaultsFromPrincipal(parentPrincipal, - type, &result); + rv = permManager->TestPermissionWithoutDefaultsFromPrincipal( + parentDocument->NodePrincipal(), type, &result); if (NS_WARN_IF(NS_FAILED(rv))) { LOG(("Failed to test the permission")); return false; @@ -1578,7 +1618,8 @@ bool AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor( if (MOZ_LOG_TEST(gAntiTrackingLog, LogLevel::Debug)) { nsCOMPtr parentPrincipalURI; - Unused << parentPrincipal->GetURI(getter_AddRefs(parentPrincipalURI)); + Unused << parentDocument->NodePrincipal()->GetURI( + getter_AddRefs(parentPrincipalURI)); LOG_SPEC( ("Testing permission type %s for %s resulted in %d (%s)", type.get(), _spec, int(result),