зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1515665 - StorageAccess::ePartitionedOrDeny must be used only for trackers, rehsan
This commit is contained in:
Родитель
8e0c688733
Коммит
e563896a47
|
@ -8083,7 +8083,14 @@ bool nsContentUtils::IsNonSubresourceInternalPolicyType(
|
|||
|
||||
// static, public
|
||||
nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForWindow(
|
||||
nsPIDOMWindowInner* aWindow) {
|
||||
nsPIDOMWindowInner* aWindow, uint32_t* aRejectedReason) {
|
||||
uint32_t rejectedReason;
|
||||
if (!aRejectedReason) {
|
||||
aRejectedReason = &rejectedReason;
|
||||
}
|
||||
|
||||
*aRejectedReason = 0;
|
||||
|
||||
if (Document* document = aWindow->GetExtantDoc()) {
|
||||
nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
|
||||
// Note that GetChannel() below may return null, but that's OK, since the
|
||||
|
@ -8091,9 +8098,10 @@ nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForWindow(
|
|||
// will only fail to notify the UI in case storage gets blocked.
|
||||
nsIChannel* channel = document->GetChannel();
|
||||
return InternalStorageAllowedForPrincipal(principal, aWindow, nullptr,
|
||||
channel);
|
||||
channel, *aRejectedReason);
|
||||
}
|
||||
|
||||
// No document? Let's return a generic rejected reason.
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
|
@ -8108,8 +8116,10 @@ nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForDocument(
|
|||
// callee is able to deal with a null channel argument, and if passed null,
|
||||
// will only fail to notify the UI in case storage gets blocked.
|
||||
nsIChannel* channel = aDoc->GetChannel();
|
||||
|
||||
uint32_t rejectedReason = 0;
|
||||
return InternalStorageAllowedForPrincipal(principal, inner, nullptr,
|
||||
channel);
|
||||
channel, rejectedReason);
|
||||
}
|
||||
|
||||
return StorageAccess::eDeny;
|
||||
|
@ -8122,7 +8132,9 @@ nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForNewWindow(
|
|||
MOZ_ASSERT(aURI);
|
||||
// parent may be nullptr
|
||||
|
||||
return InternalStorageAllowedForPrincipal(aPrincipal, aParent, aURI, nullptr);
|
||||
uint32_t rejectedReason = 0;
|
||||
return InternalStorageAllowedForPrincipal(aPrincipal, aParent, aURI, nullptr,
|
||||
rejectedReason);
|
||||
}
|
||||
|
||||
// static, public
|
||||
|
@ -8136,8 +8148,9 @@ nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForChannel(
|
|||
aChannel, getter_AddRefs(principal));
|
||||
NS_ENSURE_TRUE(principal, nsContentUtils::StorageAccess::eDeny);
|
||||
|
||||
nsContentUtils::StorageAccess result =
|
||||
InternalStorageAllowedForPrincipal(principal, nullptr, nullptr, aChannel);
|
||||
uint32_t rejectedReason = 0;
|
||||
nsContentUtils::StorageAccess result = InternalStorageAllowedForPrincipal(
|
||||
principal, nullptr, nullptr, aChannel, rejectedReason);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -8145,8 +8158,9 @@ nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForChannel(
|
|||
// static, public
|
||||
nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForPrincipal(
|
||||
nsIPrincipal* aPrincipal) {
|
||||
uint32_t rejectedReason = 0;
|
||||
return InternalStorageAllowedForPrincipal(aPrincipal, nullptr, nullptr,
|
||||
nullptr);
|
||||
nullptr, rejectedReason);
|
||||
}
|
||||
|
||||
// static, private
|
||||
|
@ -8279,14 +8293,14 @@ static bool StorageDisabledByAntiTrackingInternal(nsPIDOMWindowInner* aWindow,
|
|||
nsIChannel* aChannel,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIURI* aURI,
|
||||
uint32_t* aRejectedReason) {
|
||||
uint32_t& aRejectedReason) {
|
||||
MOZ_ASSERT(aWindow || aChannel || aPrincipal);
|
||||
|
||||
if (aWindow) {
|
||||
nsIURI* documentURI = aURI ? aURI : aWindow->GetDocumentURI();
|
||||
return !documentURI ||
|
||||
!AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
|
||||
aWindow, documentURI, aRejectedReason);
|
||||
aWindow, documentURI, &aRejectedReason);
|
||||
}
|
||||
|
||||
if (aChannel) {
|
||||
|
@ -8302,7 +8316,7 @@ static bool StorageDisabledByAntiTrackingInternal(nsPIDOMWindowInner* aWindow,
|
|||
}
|
||||
|
||||
return !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
|
||||
httpChannel, uri, aRejectedReason);
|
||||
httpChannel, uri, &aRejectedReason);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
@ -8313,23 +8327,23 @@ static bool StorageDisabledByAntiTrackingInternal(nsPIDOMWindowInner* aWindow,
|
|||
bool nsContentUtils::StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
|
||||
nsIChannel* aChannel,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIURI* aURI) {
|
||||
uint32_t rejectedReason = 0;
|
||||
nsIURI* aURI,
|
||||
uint32_t& aRejectedReason) {
|
||||
bool disabled = StorageDisabledByAntiTrackingInternal(
|
||||
aWindow, aChannel, aPrincipal, aURI, &rejectedReason);
|
||||
aWindow, aChannel, aPrincipal, aURI, aRejectedReason);
|
||||
if (sAntiTrackingControlCenterUIEnabled) {
|
||||
if (aWindow) {
|
||||
AntiTrackingCommon::NotifyBlockingDecision(
|
||||
aWindow,
|
||||
disabled ? AntiTrackingCommon::BlockingDecision::eBlock
|
||||
: AntiTrackingCommon::BlockingDecision::eAllow,
|
||||
rejectedReason);
|
||||
aRejectedReason);
|
||||
} else if (aChannel) {
|
||||
AntiTrackingCommon::NotifyBlockingDecision(
|
||||
aChannel,
|
||||
disabled ? AntiTrackingCommon::BlockingDecision::eBlock
|
||||
: AntiTrackingCommon::BlockingDecision::eAllow,
|
||||
rejectedReason);
|
||||
aRejectedReason);
|
||||
}
|
||||
}
|
||||
return disabled;
|
||||
|
@ -8340,9 +8354,12 @@ nsContentUtils::StorageAccess
|
|||
nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
|
||||
nsPIDOMWindowInner* aWindow,
|
||||
nsIURI* aURI,
|
||||
nsIChannel* aChannel) {
|
||||
nsIChannel* aChannel,
|
||||
uint32_t& aRejectedReason) {
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
aRejectedReason = 0;
|
||||
|
||||
StorageAccess access = StorageAccess::eAllow;
|
||||
|
||||
// We don't allow storage on the null principal, in general. Even if the
|
||||
|
@ -8421,13 +8438,14 @@ nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
|
|||
}
|
||||
}
|
||||
|
||||
if (!StorageDisabledByAntiTracking(aWindow, aChannel, aPrincipal, aURI)) {
|
||||
if (!StorageDisabledByAntiTracking(aWindow, aChannel, aPrincipal, aURI,
|
||||
aRejectedReason)) {
|
||||
return access;
|
||||
}
|
||||
|
||||
static const char* kPrefName =
|
||||
"privacy.restrict3rdpartystorage.partitionedHosts";
|
||||
if (IsURIInPrefList(uri, kPrefName)) {
|
||||
// We want to have a partitioned storage only for trackers.
|
||||
if (aRejectedReason ==
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER) {
|
||||
return StorageAccess::ePartitionedOrDeny;
|
||||
}
|
||||
|
||||
|
|
|
@ -2936,7 +2936,8 @@ class nsContentUtils {
|
|||
* persistent storage which are available to web pages. Cookies don't use
|
||||
* this logic, and security logic related to them must be updated separately.
|
||||
*/
|
||||
static StorageAccess StorageAllowedForWindow(nsPIDOMWindowInner* aWindow);
|
||||
static StorageAccess StorageAllowedForWindow(
|
||||
nsPIDOMWindowInner* aWindow, uint32_t* aRejectedReason = nullptr);
|
||||
|
||||
/*
|
||||
* Checks if storage for the given document is permitted by a combination of
|
||||
|
@ -2976,12 +2977,13 @@ class nsContentUtils {
|
|||
* anti-tracking feature.
|
||||
*/
|
||||
static bool StorageDisabledByAntiTracking(Document* aDocument, nsIURI* aURI) {
|
||||
uint32_t rejectedReason = 0;
|
||||
// Note that GetChannel() below may return null, but that's OK, since the
|
||||
// callee is able to deal with a null channel argument, and if passed null,
|
||||
// will only fail to notify the UI in case storage gets blocked.
|
||||
return StorageDisabledByAntiTracking(aDocument->GetInnerWindow(),
|
||||
aDocument->GetChannel(),
|
||||
aDocument->NodePrincipal(), aURI);
|
||||
return StorageDisabledByAntiTracking(
|
||||
aDocument->GetInnerWindow(), aDocument->GetChannel(),
|
||||
aDocument->NodePrincipal(), aURI, rejectedReason);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -2995,7 +2997,8 @@ class nsContentUtils {
|
|||
static bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
|
||||
nsIChannel* aChannel,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIURI* aURI);
|
||||
nsIURI* aURI,
|
||||
uint32_t& aRejectedReason);
|
||||
|
||||
public:
|
||||
/*
|
||||
|
@ -3383,7 +3386,7 @@ class nsContentUtils {
|
|||
*/
|
||||
static StorageAccess InternalStorageAllowedForPrincipal(
|
||||
nsIPrincipal* aPrincipal, nsPIDOMWindowInner* aWindow, nsIURI* aURI,
|
||||
nsIChannel* aChannel);
|
||||
nsIChannel* aChannel, uint32_t& aRejectedReason);
|
||||
|
||||
static nsINode* GetCommonAncestorHelper(nsINode* aNode1, nsINode* aNode2);
|
||||
static nsIContent* GetCommonFlattenedTreeAncestorHelper(
|
||||
|
|
|
@ -4399,6 +4399,22 @@ Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) {
|
|||
|
||||
nsContentUtils::StorageAccess access =
|
||||
nsContentUtils::StorageAllowedForWindow(this);
|
||||
|
||||
// We allow partitioned localStorage only to some hosts.
|
||||
if (access == nsContentUtils::StorageAccess::ePartitionedOrDeny) {
|
||||
if (!mDoc) {
|
||||
access = nsContentUtils::StorageAccess::eDeny;
|
||||
} else {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
Unused << mDoc->NodePrincipal()->GetURI(getter_AddRefs(uri));
|
||||
static const char* kPrefName =
|
||||
"privacy.restrict3rdpartystorage.partitionedHosts";
|
||||
if (!uri || !nsContentUtils::IsURIInPrefList(uri, kPrefName)) {
|
||||
access = nsContentUtils::StorageAccess::eDeny;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (access == nsContentUtils::StorageAccess::eDeny) {
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
|
|
|
@ -1407,7 +1407,8 @@ pref("content.sink.pending_event_mode", 0);
|
|||
// 3 = openAbused
|
||||
pref("privacy.popups.disable_from_plugins", 3);
|
||||
|
||||
// Enable Paritioned LocalStorage for a list of hosts.
|
||||
// Enable Paritioned LocalStorage for a list of hosts when detected as trackers
|
||||
// (See nsICookieService::BEHAVIOR_REJECT_TRACKER cookie behavior)
|
||||
pref("privacy.restrict3rdpartystorage.partitionedHosts", "accounts.google.com/o/oauth2/");
|
||||
|
||||
// If a host is contained in this pref list, user-interaction is required
|
||||
|
@ -1440,7 +1441,7 @@ pref("privacy.firstparty.isolate", false);
|
|||
pref("privacy.firstparty.isolate.restrict_opener_access", true);
|
||||
// We automatically decline canvas permission requests if they are not initiated
|
||||
// from user input. Just in case that breaks something, we allow the user to revert
|
||||
// this behaior with this obscure pref. We do not intend to support this long term.
|
||||
// this behavior with this obscure pref. We do not intend to support this long term.
|
||||
// If you do set it, to work around some broken website, please file a bug with
|
||||
// information so we can understand why it is needed.
|
||||
pref("privacy.resistFingerprinting.autoDeclineNoUserInputCanvasPrompts", true);
|
||||
|
|
Загрузка…
Ссылка в новой задаче