Bug 1515665 - StorageAccess::ePartitionedOrDeny must be used only for trackers, rehsan

This commit is contained in:
Andrea Marchesini 2019-01-23 19:19:19 +01:00
Родитель 8e0c688733
Коммит e563896a47
4 изменённых файлов: 66 добавлений и 28 удалений

Просмотреть файл

@ -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);