зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1480780 - Merge the privacy.3rdpartystorage.enabled pref with the network.cookie.cookieBehavior pref; r=ehsan
This patch introduces a new cookie behavior policy called BEHAVIOR_REJECT_TRACKER. It also makes it possible to override that behavior with cookie permissions similar to other cookie behaviors.
This commit is contained in:
Родитель
d65b9942a2
Коммит
d1e5833a37
|
@ -11,6 +11,7 @@
|
|||
#include "nsIXULAppInfo.h"
|
||||
#include "nsPluginArray.h"
|
||||
#include "nsMimeTypeArray.h"
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/BodyExtractor.h"
|
||||
#include "mozilla/dom/FetchBinding.h"
|
||||
|
@ -63,6 +64,7 @@
|
|||
#include "nsRFPService.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIStringStream.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
|
@ -513,15 +515,11 @@ Navigator::Storage()
|
|||
return mStorageManager;
|
||||
}
|
||||
|
||||
// Values for the network.cookie.cookieBehavior pref are documented in
|
||||
// nsCookieService.cpp.
|
||||
#define COOKIE_BEHAVIOR_REJECT 2
|
||||
|
||||
bool
|
||||
Navigator::CookieEnabled()
|
||||
{
|
||||
bool cookieEnabled = (StaticPrefs::network_cookie_cookieBehavior() !=
|
||||
COOKIE_BEHAVIOR_REJECT);
|
||||
nsICookieService::BEHAVIOR_REJECT);
|
||||
|
||||
// Check whether an exception overrides the global cookie behavior
|
||||
// Note that the code for getting the URI here matches that in
|
||||
|
@ -544,20 +542,8 @@ Navigator::CookieEnabled()
|
|||
return cookieEnabled;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICookiePermission> permMgr =
|
||||
do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
|
||||
NS_ENSURE_TRUE(permMgr, cookieEnabled);
|
||||
|
||||
// Pass null for the channel, just like the cookie service does.
|
||||
nsCookieAccess access;
|
||||
nsresult rv = permMgr->CanAccess(doc->NodePrincipal(), &access);
|
||||
NS_ENSURE_SUCCESS(rv, cookieEnabled);
|
||||
|
||||
if (access != nsICookiePermission::ACCESS_DEFAULT) {
|
||||
cookieEnabled = access != nsICookiePermission::ACCESS_DENY;
|
||||
}
|
||||
|
||||
return cookieEnabled;
|
||||
return AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(mWindow,
|
||||
codebaseURI);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -217,8 +217,8 @@
|
|||
#include "HTMLSplitOnSpacesTokenizer.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
#include "nsICookiePermission.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "mozilla/EnumSet.h"
|
||||
#include "mozilla/BloomFilter.h"
|
||||
#include "TabChild.h"
|
||||
|
@ -8751,12 +8751,10 @@ nsContentUtils::StorageAllowedForPrincipal(nsIPrincipal* aPrincipal)
|
|||
|
||||
// static, private
|
||||
void
|
||||
nsContentUtils::GetCookieBehaviorForPrincipal(nsIPrincipal* aPrincipal,
|
||||
uint32_t* aLifetimePolicy,
|
||||
uint32_t* aBehavior)
|
||||
nsContentUtils::GetCookieLifetimePolicyForPrincipal(nsIPrincipal* aPrincipal,
|
||||
uint32_t* aLifetimePolicy)
|
||||
{
|
||||
*aLifetimePolicy = sCookiesLifetimePolicy;
|
||||
*aBehavior = StaticPrefs::network_cookie_cookieBehavior();
|
||||
|
||||
// Any permissions set for the given principal will override our default
|
||||
// settings from preferences.
|
||||
|
@ -8770,19 +8768,15 @@ nsContentUtils::GetCookieBehaviorForPrincipal(nsIPrincipal* aPrincipal,
|
|||
permissionManager->TestPermissionFromPrincipal(aPrincipal, "cookie", &perm);
|
||||
switch (perm) {
|
||||
case nsICookiePermission::ACCESS_ALLOW:
|
||||
*aBehavior = nsICookieService::BEHAVIOR_ACCEPT;
|
||||
*aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
|
||||
break;
|
||||
case nsICookiePermission::ACCESS_DENY:
|
||||
*aBehavior = nsICookieService::BEHAVIOR_REJECT;
|
||||
*aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
|
||||
break;
|
||||
case nsICookiePermission::ACCESS_SESSION:
|
||||
*aBehavior = nsICookieService::BEHAVIOR_ACCEPT;
|
||||
*aLifetimePolicy = nsICookieService::ACCEPT_SESSION;
|
||||
break;
|
||||
case nsICookiePermission::ACCESS_ALLOW_FIRST_PARTY_ONLY:
|
||||
*aBehavior = nsICookieService::BEHAVIOR_REJECT_FOREIGN;
|
||||
// NOTE: The decision was made here to override the lifetime policy to be
|
||||
// ACCEPT_NORMALLY for consistency with ACCESS_ALLOW, but this does
|
||||
// prevent us from expressing BEHAVIOR_REJECT_FOREIGN/ACCEPT_SESSION for a
|
||||
|
@ -8791,7 +8785,6 @@ nsContentUtils::GetCookieBehaviorForPrincipal(nsIPrincipal* aPrincipal,
|
|||
*aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
|
||||
break;
|
||||
case nsICookiePermission::ACCESS_LIMIT_THIRD_PARTY:
|
||||
*aBehavior = nsICookieService::BEHAVIOR_LIMIT_FOREIGN;
|
||||
// NOTE: The decision was made here to override the lifetime policy to be
|
||||
// ACCEPT_NORMALLY for consistency with ACCESS_ALLOW, but this does
|
||||
// prevent us from expressing BEHAVIOR_REJECT_FOREIGN/ACCEPT_SESSION for a
|
||||
|
@ -8861,71 +8854,47 @@ nsContentUtils::IsTrackingResourceWindow(nsPIDOMWindowInner* aWindow)
|
|||
static bool
|
||||
StorageDisabledByAntiTrackingInternal(nsPIDOMWindowInner* aWindow,
|
||||
nsIChannel* aChannel,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
if (!StaticPrefs::privacy_restrict3rdpartystorage_enabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let's check if this is a 3rd party context.
|
||||
if (!nsContentUtils::IsThirdPartyWindowOrChannel(aWindow, aChannel, aURI)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(aWindow || aChannel || aPrincipal);
|
||||
|
||||
if (aWindow) {
|
||||
nsGlobalWindowInner* innerWindow = nsGlobalWindowInner::Cast(aWindow);
|
||||
nsGlobalWindowOuter* outerWindow =
|
||||
nsGlobalWindowOuter::Cast(innerWindow->GetOuterWindow());
|
||||
if (NS_WARN_IF(!outerWindow)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are a first party resource.
|
||||
if (outerWindow->IsTopLevelWindow()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIURI* documentURI = aURI ? aURI : aWindow->GetDocumentURI();
|
||||
if (documentURI &&
|
||||
AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(aWindow,
|
||||
documentURI)) {
|
||||
return !documentURI ||
|
||||
!AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(aWindow,
|
||||
documentURI);
|
||||
}
|
||||
|
||||
if (aChannel) {
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (!httpChannel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = httpChannel->GetURI(getter_AddRefs(uri));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
|
||||
uri);
|
||||
}
|
||||
|
||||
// aChannel and aWindow are mutually exclusive.
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (!httpChannel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is not a tracking resource, nothing is disabled.
|
||||
if (!httpChannel->GetIsTrackingResource()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = httpChannel->GetURI(getter_AddRefs(uri));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
|
||||
uri);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
return !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(aPrincipal);
|
||||
}
|
||||
|
||||
// static public
|
||||
bool
|
||||
nsContentUtils::StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
|
||||
nsIChannel* aChannel,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
bool disabled =
|
||||
StorageDisabledByAntiTrackingInternal(aWindow, aChannel, aURI);
|
||||
StorageDisabledByAntiTrackingInternal(aWindow, aChannel, aPrincipal, aURI);
|
||||
if (disabled &&
|
||||
StaticPrefs::privacy_restrict3rdpartystorage_ui_enabled()) {
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
|
||||
|
@ -8933,6 +8902,8 @@ nsContentUtils::StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
|
|||
return false;
|
||||
}
|
||||
|
||||
// FIXME: this is wrong. This method is called also with aWindow and a null
|
||||
// aChannel.
|
||||
nsCOMPtr<mozIDOMWindowProxy> win;
|
||||
nsresult rv = thirdPartyUtil->GetTopWindowForChannel(aChannel,
|
||||
getter_AddRefs(win));
|
||||
|
@ -8962,10 +8933,6 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
|
|||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
if (StorageDisabledByAntiTracking(aWindow, aChannel, aURI)) {
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
if (aWindow) {
|
||||
// If the document is sandboxed, then it is not permitted to use storage
|
||||
nsIDocument* document = aWindow->GetExtantDoc();
|
||||
|
@ -8980,17 +8947,15 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
|
|||
}
|
||||
|
||||
uint32_t lifetimePolicy;
|
||||
uint32_t behavior;
|
||||
|
||||
// WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior
|
||||
// and ACCEPT_NORMALLY as lifetimePolicy (See Bug 1406675 for rationale).
|
||||
auto policy = BasePrincipal::Cast(aPrincipal)->AddonPolicy();
|
||||
|
||||
if (policy) {
|
||||
behavior = nsICookieService::BEHAVIOR_ACCEPT;
|
||||
lifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
|
||||
} else {
|
||||
GetCookieBehaviorForPrincipal(aPrincipal, &lifetimePolicy, &behavior);
|
||||
GetCookieLifetimePolicyForPrincipal(aPrincipal, &lifetimePolicy);
|
||||
}
|
||||
|
||||
// Check if we should only allow storage for the session, and record that fact
|
||||
|
@ -9036,19 +9001,7 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
|
|||
}
|
||||
}
|
||||
|
||||
// We don't want to prompt for every attempt to access permissions.
|
||||
if (behavior == nsICookieService::BEHAVIOR_REJECT) {
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
if ((behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
|
||||
behavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN) &&
|
||||
IsThirdPartyWindowOrChannel(aWindow, aChannel, aURI)) {
|
||||
// XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
|
||||
// simply rejecting the request to use the storage. In the future, if we
|
||||
// change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
|
||||
// for non-cookie storage types, this may change.
|
||||
|
||||
if (StorageDisabledByAntiTracking(aWindow, aChannel, aPrincipal, aURI)) {
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
|
|
|
@ -2951,11 +2951,12 @@ public:
|
|||
static StorageAccess StorageAllowedForPrincipal(nsIPrincipal* aPrincipal);
|
||||
|
||||
/*
|
||||
* Returns true if this window/channel should disable storages because of the
|
||||
* anti-tracking feature.
|
||||
* Returns true if this window/channel/aPrincipal should disable storages
|
||||
* because of the anti-tracking feature.
|
||||
*/
|
||||
static bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
|
||||
nsIChannel* aChannel,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIURI* aURI);
|
||||
|
||||
/*
|
||||
|
@ -3342,14 +3343,13 @@ private:
|
|||
void* aArg);
|
||||
|
||||
/**
|
||||
* Gets the current cookie lifetime policy and cookie behavior for a given
|
||||
* principal by checking with preferences and the permission manager.
|
||||
* Gets the current cookie lifetime policy for a given principal by checking
|
||||
* with preferences and the permission manager.
|
||||
*
|
||||
* Used in the implementation of InternalStorageAllowedForPrincipal.
|
||||
*/
|
||||
static void GetCookieBehaviorForPrincipal(nsIPrincipal* aPrincipal,
|
||||
uint32_t* aLifetimePolicy,
|
||||
uint32_t* aBehavior);
|
||||
static void GetCookieLifetimePolicyForPrincipal(nsIPrincipal* aPrincipal,
|
||||
uint32_t* aLifetimePolicy);
|
||||
|
||||
/*
|
||||
* Checks if storage for a given principal is permitted by the user's
|
||||
|
|
|
@ -12643,7 +12643,8 @@ nsIDocument::SetDocTreeHadPlayRevoked()
|
|||
void
|
||||
nsIDocument::MaybeAllowStorageForOpener()
|
||||
{
|
||||
if (!StaticPrefs::privacy_restrict3rdpartystorage_enabled()) {
|
||||
if (StaticPrefs::network_cookie_cookieBehavior() !=
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#include "nsIBFCacheEntry.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
|
@ -73,12 +73,14 @@ class InitializeRunnable final : public WorkerMainThreadRunnable
|
|||
{
|
||||
public:
|
||||
InitializeRunnable(ThreadSafeWorkerRef* aWorkerRef, nsACString& aOrigin,
|
||||
PrincipalInfo& aPrincipalInfo, ErrorResult& aRv)
|
||||
PrincipalInfo& aPrincipalInfo, bool* aThirdPartyWindow,
|
||||
ErrorResult& aRv)
|
||||
: WorkerMainThreadRunnable(aWorkerRef->Private(),
|
||||
NS_LITERAL_CSTRING("BroadcastChannel :: Initialize"))
|
||||
, mWorkerRef(aWorkerRef)
|
||||
, mOrigin(aOrigin)
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
, mThirdPartyWindow(aThirdPartyWindow)
|
||||
, mRv(aRv)
|
||||
{
|
||||
MOZ_ASSERT(mWorkerRef);
|
||||
|
@ -116,6 +118,9 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
*mThirdPartyWindow =
|
||||
nsContentUtils::IsThirdPartyWindowOrChannel(window, nullptr, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -123,6 +128,7 @@ private:
|
|||
RefPtr<ThreadSafeWorkerRef> mWorkerRef;
|
||||
nsACString& mOrigin;
|
||||
PrincipalInfo& mPrincipalInfo;
|
||||
bool* mThirdPartyWindow;
|
||||
ErrorResult& mRv;
|
||||
};
|
||||
|
||||
|
@ -301,7 +307,8 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (StaticPrefs::privacy_restrict3rdpartystorage_enabled() &&
|
||||
if (nsContentUtils::IsThirdPartyWindowOrChannel(window, nullptr,
|
||||
nullptr) &&
|
||||
nsContentUtils::StorageAllowedForWindow(window) !=
|
||||
nsContentUtils::StorageAccess::eAllow) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
|
@ -313,12 +320,6 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
|||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
if (StaticPrefs::privacy_restrict3rdpartystorage_enabled() &&
|
||||
!workerPrivate->IsStorageAllowed()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<StrongWorkerRef> workerRef =
|
||||
StrongWorkerRef::Create(workerPrivate, "BroadcastChannel",
|
||||
[bc] () { bc->Shutdown(); });
|
||||
|
@ -331,13 +332,21 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
|
|||
|
||||
RefPtr<ThreadSafeWorkerRef> tsr = new ThreadSafeWorkerRef(workerRef);
|
||||
|
||||
bool thirdPartyWindow = false;
|
||||
|
||||
RefPtr<InitializeRunnable> runnable =
|
||||
new InitializeRunnable(tsr, origin, principalInfo, aRv);
|
||||
new InitializeRunnable(tsr, origin, principalInfo, &thirdPartyWindow,
|
||||
aRv);
|
||||
runnable->Dispatch(Canceling, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (thirdPartyWindow && !workerPrivate->IsStorageAllowed()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bc->mWorkerRef = std::move(workerRef);
|
||||
}
|
||||
|
||||
|
|
|
@ -1107,7 +1107,7 @@ nsHTMLDocument::GetCookie(nsAString& aCookie, ErrorResult& rv)
|
|||
}
|
||||
|
||||
if (nsContentUtils::StorageDisabledByAntiTracking(GetInnerWindow(), nullptr,
|
||||
nullptr)) {
|
||||
NodePrincipal(), nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1162,7 +1162,7 @@ nsHTMLDocument::SetCookie(const nsAString& aCookie, ErrorResult& rv)
|
|||
}
|
||||
|
||||
if (nsContentUtils::StorageDisabledByAntiTracking(GetInnerWindow(), nullptr,
|
||||
nullptr)) {
|
||||
NodePrincipal(), nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
|
@ -2268,7 +2269,8 @@ RuntimeService::PropagateFirstPartyStorageAccessGranted(nsPIDOMWindowInner* aWin
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(StaticPrefs::privacy_restrict3rdpartystorage_enabled());
|
||||
MOZ_ASSERT(StaticPrefs::network_cookie_cookieBehavior() ==
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER);
|
||||
|
||||
nsTArray<WorkerPrivate*> workers;
|
||||
GetWorkersForWindow(aWindow, workers);
|
||||
|
@ -2881,7 +2883,8 @@ void
|
|||
PropagateFirstPartyStorageAccessGrantedToWorkers(nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(StaticPrefs::privacy_restrict3rdpartystorage_enabled());
|
||||
MOZ_ASSERT(StaticPrefs::network_cookie_cookieBehavior() ==
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER);
|
||||
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
if (runtime) {
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/ServiceWorkerManager.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
|
@ -141,20 +141,13 @@ ImageCacheKey::GetSpecialCaseDocumentToken(nsIDocument* aDocument, nsIURI* aURI)
|
|||
return aDocument;
|
||||
}
|
||||
|
||||
// We want to have a unique image cache if the anti-tracking feature is
|
||||
// enabled for 3rd party resources.
|
||||
if (!StaticPrefs::privacy_restrict3rdpartystorage_enabled() ||
|
||||
!nsContentUtils::IsThirdPartyWindowOrChannel(aDocument->GetInnerWindow(),
|
||||
nullptr, aURI)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If the window is 3rd party resource, let's see if the first party storage
|
||||
// access is granted for this image.
|
||||
if (nsContentUtils::IsTrackingResourceWindow(aDocument->GetInnerWindow())) {
|
||||
return nsContentUtils::StorageDisabledByAntiTracking(aDocument->GetInnerWindow(),
|
||||
nullptr, aURI)
|
||||
? aDocument : nullptr;
|
||||
// If we must disable the storage, we want to create a unique cache key for
|
||||
// this image.
|
||||
if (nsContentUtils::StorageDisabledByAntiTracking(aDocument->GetInnerWindow(),
|
||||
nullptr,
|
||||
aDocument->NodePrincipal(),
|
||||
aURI)) {
|
||||
return aDocument;
|
||||
}
|
||||
|
||||
// Another scenario is if this image is a 3rd party resource loaded by a
|
||||
|
@ -163,7 +156,8 @@ ImageCacheKey::GetSpecialCaseDocumentToken(nsIDocument* aDocument, nsIURI* aURI)
|
|||
// this point. The best approach here is to be conservative: if we are sure
|
||||
// that the permission is granted, let's return a nullptr. Otherwise, let's
|
||||
// make a unique image cache.
|
||||
if (!AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(aDocument->GetInnerWindow(),
|
||||
if (!aDocument->IsCookieAverse() &&
|
||||
!AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(aDocument->GetInnerWindow(),
|
||||
aURI)) {
|
||||
return aDocument;
|
||||
}
|
||||
|
|
|
@ -1091,12 +1091,13 @@ VARCACHE_PREF(
|
|||
bool, false
|
||||
)
|
||||
|
||||
// 0-Accept, 1-dontAcceptForeign, 2-dontAcceptAny, 3-limitForeign
|
||||
// 0-Accept, 1-dontAcceptForeign, 2-dontAcceptAny, 3-limitForeign,
|
||||
// 4-rejectTracker
|
||||
// Keep the old default of accepting all cookies
|
||||
VARCACHE_PREF(
|
||||
"network.cookie.cookieBehavior",
|
||||
network_cookie_cookieBehavior,
|
||||
int32_t, 0
|
||||
RelaxedAtomicInt32, 0
|
||||
)
|
||||
|
||||
// Enables the predictive service.
|
||||
|
@ -1231,12 +1232,6 @@ PREF("preferences.allow.omt-write", bool, true)
|
|||
// Privacy prefs
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
VARCACHE_PREF(
|
||||
"privacy.restrict3rdpartystorage.enabled",
|
||||
privacy_restrict3rdpartystorage_enabled,
|
||||
RelaxedAtomicBool, false
|
||||
)
|
||||
|
||||
VARCACHE_PREF(
|
||||
"privacy.restrict3rdpartystorage.ui.enabled",
|
||||
privacy_restrict3rdpartystorage_ui_enabled,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsIAddonPolicyService.h"
|
||||
#include "nsICacheEntry.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIClassOfService.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
@ -951,7 +952,8 @@ TrackingURICallback::OnClassifyComplete(nsresult aErrorCode,
|
|||
mChannelClassifier->ShouldEnableTrackingProtection();
|
||||
const bool shouldEnableTrackingAnnotation =
|
||||
mChannelClassifier->ShouldEnableTrackingAnnotation() ||
|
||||
StaticPrefs::privacy_restrict3rdpartystorage_enabled();
|
||||
StaticPrefs::network_cookie_cookieBehavior() ==
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER;
|
||||
MOZ_ASSERT(shouldEnableTrackingProtection || shouldEnableTrackingAnnotation);
|
||||
|
||||
LOG(("TrackingURICallback[%p]:OnClassifyComplete "
|
||||
|
@ -1199,7 +1201,8 @@ TrackingURICallback::OnTrackerFound(nsresult aErrorCode)
|
|||
} else {
|
||||
MOZ_ASSERT(aErrorCode == NS_ERROR_TRACKING_ANNOTATION_URI);
|
||||
MOZ_ASSERT(mChannelClassifier->ShouldEnableTrackingAnnotation() ||
|
||||
StaticPrefs::privacy_restrict3rdpartystorage_enabled());
|
||||
StaticPrefs::network_cookie_cookieBehavior() ==
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER);
|
||||
|
||||
LOG(("TrackingURICallback[%p]::OnTrackerFound, annotating channel[%p]",
|
||||
mChannelClassifier.get(), channel.get()));
|
||||
|
@ -1421,7 +1424,8 @@ nsChannelClassifier::CheckIsTrackerWithLocalTable(std::function<void()>&& aCallb
|
|||
}
|
||||
|
||||
const bool shouldEnableTrackingProtection = ShouldEnableTrackingProtection();
|
||||
const bool shouldEnableTrackingAnnotation = ShouldEnableTrackingAnnotation() || StaticPrefs::privacy_restrict3rdpartystorage_enabled();
|
||||
const bool shouldEnableTrackingAnnotation = ShouldEnableTrackingAnnotation() ||
|
||||
StaticPrefs::network_cookie_cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER;
|
||||
if (!shouldEnableTrackingProtection && !shouldEnableTrackingAnnotation) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -2410,7 +2410,7 @@ nsCookieService::PrefChanged(nsIPrefBranch *aPrefBranch)
|
|||
{
|
||||
int32_t val;
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookieBehavior, &val)))
|
||||
mCookieBehavior = (uint8_t) LIMIT(val, 0, 3, 0);
|
||||
mCookieBehavior = (uint8_t) LIMIT(val, 0, nsICookieService::BEHAVIOR_LAST, 0);
|
||||
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefMaxNumberOfCookies, &val)))
|
||||
mMaxNumberOfCookies = (uint16_t) LIMIT(val, 1, 0xFFFF, kMaxNumberOfCookies);
|
||||
|
@ -4199,14 +4199,6 @@ nsCookieService::CheckPrefs(nsICookiePermission *aPermissionService,
|
|||
return STATUS_REJECTED_WITH_ERROR;
|
||||
}
|
||||
|
||||
// No cookies allowed if this request comes from a tracker, in a 3rd party
|
||||
// context, when anti-tracking protection is enabled and when we don't have
|
||||
// access to the first-party cookie jar.
|
||||
if (aIsForeign && aIsTrackingResource && !aFirstPartyStorageAccessGranted &&
|
||||
StaticPrefs::privacy_restrict3rdpartystorage_enabled()) {
|
||||
return STATUS_REJECTED;
|
||||
}
|
||||
|
||||
// check the permission list first; if we find an entry, it overrides
|
||||
// default prefs. see bug 184059.
|
||||
if (aPermissionService) {
|
||||
|
@ -4250,6 +4242,15 @@ nsCookieService::CheckPrefs(nsICookiePermission *aPermissionService,
|
|||
}
|
||||
}
|
||||
|
||||
// No cookies allowed if this request comes from a tracker, in a 3rd party
|
||||
// context, when anti-tracking protection is enabled and when we don't have
|
||||
// access to the first-party cookie jar.
|
||||
if (aIsForeign && aIsTrackingResource && !aFirstPartyStorageAccessGranted &&
|
||||
aCookieBehavior == nsICookieService::BEHAVIOR_REJECT_TRACKER) {
|
||||
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "cookies are disabled in trackers");
|
||||
return STATUS_REJECTED;
|
||||
}
|
||||
|
||||
// check default prefs
|
||||
if (aCookieBehavior == nsICookieService::BEHAVIOR_REJECT) {
|
||||
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "cookies are disabled");
|
||||
|
@ -4271,7 +4272,9 @@ nsCookieService::CheckPrefs(nsICookiePermission *aPermissionService,
|
|||
}
|
||||
|
||||
MOZ_ASSERT(aCookieBehavior == nsICookieService::BEHAVIOR_ACCEPT ||
|
||||
aCookieBehavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN);
|
||||
aCookieBehavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN ||
|
||||
// But with permission granted.
|
||||
aCookieBehavior == nsICookieService::BEHAVIOR_REJECT_TRACKER);
|
||||
|
||||
if (aThirdPartySession)
|
||||
return STATUS_ACCEPT_SESSION;
|
||||
|
|
|
@ -52,7 +52,7 @@ interface nsICookiePermission : nsISupports
|
|||
/**
|
||||
* canAccess
|
||||
*
|
||||
* this method is called to test whether or not the given URI/channel may
|
||||
* this method is called to test whether or not the given principal may
|
||||
* access the cookie database, either to set or get cookies.
|
||||
*
|
||||
* @param aPrincipal
|
||||
|
|
|
@ -89,6 +89,9 @@ interface nsICookieService : nsISupports
|
|||
const uint32_t BEHAVIOR_REJECT = 2; // reject all cookies
|
||||
const uint32_t BEHAVIOR_LIMIT_FOREIGN = 3; // reject third-party cookies unless the
|
||||
// eTLD already has at least one cookie
|
||||
const uint32_t BEHAVIOR_REJECT_TRACKER = 4; // reject trackers
|
||||
// When adding a new cookie behavior, please increase this value!
|
||||
const uint32_t BEHAVIOR_LAST = 4;
|
||||
|
||||
/*
|
||||
* Possible values for the "network.cookie.lifetimePolicy" preference.
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "nsICacheStorage.h"
|
||||
#include "nsICacheEntry.h"
|
||||
#include "nsICaptivePortalService.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsICryptoHash.h"
|
||||
#include "nsINetworkInterceptController.h"
|
||||
#include "nsINSSErrorsService.h"
|
||||
|
@ -55,6 +56,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -103,7 +105,6 @@
|
|||
#include "mozilla/net/Predictor.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "CacheControlParser.h"
|
||||
#include "nsMixedContentBlocker.h"
|
||||
#include "CacheStorageService.h"
|
||||
|
@ -3827,28 +3828,18 @@ nsHttpChannel::OpenCacheEntryInternal(bool isHttps,
|
|||
extension.Append("TRR");
|
||||
}
|
||||
|
||||
if (StaticPrefs::privacy_restrict3rdpartystorage_enabled() &&
|
||||
mIsTrackingResource) {
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
services::GetThirdPartyUtil();
|
||||
if (thirdPartyUtil) {
|
||||
bool thirdParty = false;
|
||||
Unused << thirdPartyUtil->IsThirdPartyChannel(this,
|
||||
nullptr,
|
||||
&thirdParty);
|
||||
if (thirdParty) {
|
||||
nsCOMPtr<nsIURI> topWindowURI;
|
||||
rv = GetTopWindowURI(getter_AddRefs(topWindowURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(this, mURI)) {
|
||||
nsCOMPtr<nsIURI> topWindowURI;
|
||||
rv = GetTopWindowURI(getter_AddRefs(topWindowURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString topWindowOrigin;
|
||||
rv = nsContentUtils::GetUTFOrigin(topWindowURI, topWindowOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsAutoString topWindowOrigin;
|
||||
rv = nsContentUtils::GetUTFOrigin(topWindowURI ? topWindowURI : mURI,
|
||||
topWindowOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
extension.Append("-trackerFor:");
|
||||
extension.Append(NS_ConvertUTF16toUTF8(topWindowOrigin));
|
||||
}
|
||||
}
|
||||
extension.Append("-unique:");
|
||||
extension.Append(NS_ConvertUTF16toUTF8(topWindowOrigin));
|
||||
}
|
||||
|
||||
mCacheOpenWithPriority = cacheEntryOpenFlags & nsICacheStorage::OPEN_PRIORITY;
|
||||
|
|
|
@ -479,7 +479,7 @@ interface nsIHttpChannel : nsIChannel
|
|||
* protection list. This is only available if the
|
||||
* privacy.trackingprotection.annotate_channels pref is set and its value
|
||||
* should only be relied on after the channel has established a connection.
|
||||
* Note that, if privacy.restrict3rdpartystorage.enabled pref is set, also
|
||||
* Note that, if the privacy.trackingprotection.annotate_channels pref is set, also
|
||||
* top-level channels could be marked as tracking resource.
|
||||
*/
|
||||
[infallible] readonly attribute boolean isTrackingResource;
|
||||
|
|
|
@ -13,10 +13,13 @@
|
|||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGlobalWindowInner.h"
|
||||
#include "nsICookiePermission.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "prtime.h"
|
||||
|
||||
#define ANTITRACKING_PERM_KEY "3rdPartyStorage"
|
||||
|
@ -71,6 +74,43 @@ CreatePermissionKey(const nsCString& aTrackingOrigin,
|
|||
aGrantedOrigin.get());
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (!aPrincipal->GetIsCodebasePrincipal()) {
|
||||
return access;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICookiePermission> cps =
|
||||
do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
|
||||
if (NS_WARN_IF(!cps)) {
|
||||
return access;
|
||||
}
|
||||
|
||||
nsresult rv = cps->CanAccess(aPrincipal, &access);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return access;
|
||||
}
|
||||
|
||||
// If we have a custom cookie permission, let's use it.
|
||||
return access;
|
||||
}
|
||||
|
||||
int32_t
|
||||
CookiesBehavior(nsIPrincipal* 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();
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
|
||||
/* static */ RefPtr<AntiTrackingCommon::StorageAccessGrantPromise>
|
||||
|
@ -79,7 +119,8 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(const nsAString& aOrigi
|
|||
{
|
||||
MOZ_ASSERT(aParentWindow);
|
||||
|
||||
if (!StaticPrefs::privacy_restrict3rdpartystorage_enabled()) {
|
||||
if (StaticPrefs::network_cookie_cookieBehavior() !=
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
|
||||
return StorageAccessGrantPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
|
@ -175,25 +216,60 @@ AntiTrackingCommon::SaveFirstPartyStorageAccessGrantedForOriginOnParentProcess(n
|
|||
}
|
||||
|
||||
bool
|
||||
AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* a3rdPartyTrackingWindow,
|
||||
AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aWindow,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
MOZ_ASSERT(a3rdPartyTrackingWindow);
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
if (!StaticPrefs::privacy_restrict3rdpartystorage_enabled()) {
|
||||
nsGlobalWindowInner* innerWindow = nsGlobalWindowInner::Cast(aWindow);
|
||||
nsIPrincipal* toplevelPrincipal = innerWindow->GetTopLevelPrincipal();
|
||||
if (!toplevelPrincipal) {
|
||||
// We are already the top-level principal. Let's use the window's principal.
|
||||
toplevelPrincipal = innerWindow->GetPrincipal();
|
||||
}
|
||||
|
||||
if (!toplevelPrincipal) {
|
||||
// This should not be possible, right?
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCookieAccess access = CheckCookiePermissionForPrincipal(toplevelPrincipal);
|
||||
if (access != nsICookiePermission::ACCESS_DEFAULT) {
|
||||
return access != nsICookiePermission::ACCESS_DENY;
|
||||
}
|
||||
|
||||
int32_t behavior = CookiesBehavior(toplevelPrincipal);
|
||||
if (behavior == nsICookieService::BEHAVIOR_ACCEPT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::IsThirdPartyWindowOrChannel(a3rdPartyTrackingWindow,
|
||||
nullptr, aURI) ||
|
||||
!nsContentUtils::IsTrackingResourceWindow(a3rdPartyTrackingWindow)) {
|
||||
if (behavior == nsICookieService::BEHAVIOR_REJECT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let's check if this is a 3rd party context.
|
||||
if (!nsContentUtils::IsThirdPartyWindowOrChannel(aWindow, nullptr, aURI)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
|
||||
behavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN) {
|
||||
// XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
|
||||
// simply rejecting the request to use the storage. In the future, if we
|
||||
// change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
|
||||
// for non-cookie storage types, this may change.
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER);
|
||||
if (!nsContentUtils::IsTrackingResourceWindow(aWindow)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> parentPrincipal;
|
||||
nsAutoCString trackingOrigin;
|
||||
if (!GetParentPrincipalAndTrackingOrigin(nsGlobalWindowInner::Cast(a3rdPartyTrackingWindow),
|
||||
if (!GetParentPrincipalAndTrackingOrigin(nsGlobalWindowInner::Cast(aWindow),
|
||||
getter_AddRefs(parentPrincipal),
|
||||
trackingOrigin)) {
|
||||
return false;
|
||||
|
@ -228,13 +304,90 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel
|
|||
{
|
||||
MOZ_ASSERT(aURI);
|
||||
MOZ_ASSERT(aChannel);
|
||||
MOZ_ASSERT(aChannel->GetIsTrackingResource());
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
|
||||
if (!loadInfo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to find the correct principal to check the cookie permission. For
|
||||
// third-party contexts, we want to check if the top-level window has a custom
|
||||
// cookie permission.
|
||||
nsIPrincipal* toplevelPrincipal = loadInfo->TopLevelPrincipal();
|
||||
|
||||
// If this is already the top-level window, we should use the loading
|
||||
// principal.
|
||||
if (!toplevelPrincipal) {
|
||||
toplevelPrincipal = loadInfo->LoadingPrincipal();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> channelPrincipal;
|
||||
nsIScriptSecurityManager* ssm = nsScriptSecurityManager::GetScriptSecurityManager();
|
||||
nsresult rv = ssm->GetChannelResultPrincipal(aChannel,
|
||||
getter_AddRefs(channelPrincipal));
|
||||
|
||||
// If we don't have a loading principal and this is a document channel, we are
|
||||
// a top-level window!
|
||||
if (!toplevelPrincipal) {
|
||||
bool isDocument = false;
|
||||
nsresult rv2 = aChannel->GetIsMainDocumentChannel(&isDocument);
|
||||
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv2) && isDocument) {
|
||||
toplevelPrincipal = channelPrincipal;
|
||||
}
|
||||
}
|
||||
|
||||
// Let's use the triggering principal then.
|
||||
if (!toplevelPrincipal) {
|
||||
toplevelPrincipal = loadInfo->TriggeringPrincipal();
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!toplevelPrincipal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCookieAccess access = CheckCookiePermissionForPrincipal(toplevelPrincipal);
|
||||
if (access != nsICookiePermission::ACCESS_DEFAULT) {
|
||||
return access != nsICookiePermission::ACCESS_DENY;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv) || !channelPrincipal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t behavior = CookiesBehavior(channelPrincipal);
|
||||
if (behavior == nsICookieService::BEHAVIOR_ACCEPT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (behavior == nsICookieService::BEHAVIOR_REJECT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
|
||||
if (!thirdPartyUtil) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool thirdParty = false;
|
||||
Unused << thirdPartyUtil->IsThirdPartyChannel(aChannel,
|
||||
nullptr,
|
||||
&thirdParty);
|
||||
// Grant if it's not a 3rd party.
|
||||
if (!thirdParty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (behavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
|
||||
behavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN) {
|
||||
// XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
|
||||
// simply rejecting the request to use the storage. In the future, if we
|
||||
// change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
|
||||
// for non-cookie storage types, this may change.
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER);
|
||||
|
||||
nsIPrincipal* parentPrincipal = loadInfo->TopLevelStorageAreaPrincipal();
|
||||
if (!parentPrincipal) {
|
||||
// parentPrincipal can be null if the parent window is not the top-level
|
||||
|
@ -250,8 +403,15 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel
|
|||
}
|
||||
}
|
||||
|
||||
// Not a tracker.
|
||||
if (!aChannel->GetIsTrackingResource()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Let's see if we have to grant the access for this particular channel.
|
||||
|
||||
nsCOMPtr<nsIURI> trackingURI;
|
||||
nsresult rv = aChannel->GetURI(getter_AddRefs(trackingURI));
|
||||
rv = aChannel->GetURI(getter_AddRefs(trackingURI));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
@ -286,6 +446,20 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel
|
|||
return result == nsIPermissionManager::ALLOW_ACTION;
|
||||
}
|
||||
|
||||
bool
|
||||
AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
nsCookieAccess access = CheckCookiePermissionForPrincipal(aPrincipal);
|
||||
if (access != nsICookiePermission::ACCESS_DEFAULT) {
|
||||
return access != nsICookiePermission::ACCESS_DENY;
|
||||
}
|
||||
|
||||
int32_t behavior = CookiesBehavior(aPrincipal);
|
||||
return behavior != nsICookieService::BEHAVIOR_REJECT;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aFirstPartyWindow,
|
||||
nsIURI* aURI)
|
||||
|
@ -294,7 +468,8 @@ AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner*
|
|||
MOZ_ASSERT(!nsContentUtils::IsTrackingResourceWindow(aFirstPartyWindow));
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
if (!StaticPrefs::privacy_restrict3rdpartystorage_enabled()) {
|
||||
if (StaticPrefs::network_cookie_cookieBehavior() !=
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -309,6 +484,11 @@ AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner*
|
|||
return false;
|
||||
}
|
||||
|
||||
nsCookieAccess access = CheckCookiePermissionForPrincipal(parentPrincipal);
|
||||
if (access != nsICookiePermission::ACCESS_DEFAULT) {
|
||||
return access != nsICookiePermission::ACCESS_DENY;
|
||||
}
|
||||
|
||||
nsAutoString origin;
|
||||
nsresult rv = nsContentUtils::GetUTFOrigin(aURI, origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
|
|
@ -46,12 +46,15 @@ public:
|
|||
MaybeIsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aFirstPartyWindow,
|
||||
nsIURI* aURI);
|
||||
|
||||
// This can be called only if the a3rdPartyTrackingChannel is _really_ a 3rd
|
||||
// party context and marked as tracking resource.
|
||||
// It returns true if the URI has access to the first party storage.
|
||||
// aChannel can be a 3rd party channel, or not.
|
||||
static bool
|
||||
IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* a3rdPartyTrackingChannel,
|
||||
nsIURI* aURI);
|
||||
IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel, nsIURI* aURI);
|
||||
|
||||
// This method checks if the principal has the permission to access to the
|
||||
// first party storage.
|
||||
static bool
|
||||
IsFirstPartyStorageAccessGrantedFor(nsIPrincipal* aPrincipal);
|
||||
|
||||
// Grant the permission for aOrigin to have access to the first party storage.
|
||||
// This method can handle 2 different scenarios:
|
||||
|
|
|
@ -5,7 +5,7 @@ add_task(async function() {
|
|||
|
||||
await SpecialPowers.flushPrefEnv();
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["privacy.restrict3rdpartystorage.enabled", true],
|
||||
["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER],
|
||||
["privacy.trackingprotection.enabled", false],
|
||||
["privacy.trackingprotection.pbmode.enabled", false],
|
||||
["privacy.trackingprotection.annotate_channels", true],
|
||||
|
|
|
@ -5,7 +5,7 @@ add_task(async function() {
|
|||
|
||||
await SpecialPowers.flushPrefEnv();
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["privacy.restrict3rdpartystorage.enabled", true],
|
||||
["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER],
|
||||
["privacy.trackingprotection.enabled", false],
|
||||
["privacy.trackingprotection.pbmode.enabled", false],
|
||||
["privacy.trackingprotection.annotate_channels", true],
|
||||
|
|
|
@ -39,7 +39,7 @@ this.AntiTracking = {
|
|||
async _setupTest(blocking, extraPrefs) {
|
||||
await SpecialPowers.flushPrefEnv();
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["privacy.restrict3rdpartystorage.enabled", blocking],
|
||||
["network.cookie.cookieBehavior", blocking ? Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER : Ci.nsICookieService.BEHAVIOR_ACCEPT],
|
||||
["privacy.trackingprotection.enabled", false],
|
||||
["privacy.trackingprotection.pbmode.enabled", false],
|
||||
["privacy.trackingprotection.annotate_channels", blocking],
|
||||
|
|
Загрузка…
Ссылка в новой задаче