Bug 1654649 - Deny requestStorageAccess for sites with denied cookie permission. r=timhuang

Differential Revision: https://phabricator.services.mozilla.com/D99802
This commit is contained in:
Paul Zuehlcke 2020-12-16 16:45:18 +00:00
parent 59f54d77e1
commit be3f13ec21
6 changed files with 60 additions and 6 deletions

View file

@ -16564,7 +16564,17 @@ already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccess(
// user for explicit permission. Reject if some rule is not fulfilled. // user for explicit permission. Reject if some rule is not fulfilled.
if (CookieJarSettings()->GetRejectThirdPartyContexts()) { if (CookieJarSettings()->GetRejectThirdPartyContexts()) {
// Only do something special for third-party tracking content. // Only do something special for third-party tracking content.
if (StorageDisabledByAntiTracking(this, nullptr)) { uint32_t antiTrackingRejectedReason = 0;
if (StorageDisabledByAntiTracking(this, nullptr,
antiTrackingRejectedReason)) {
// If storage is disabled because of a custom cookie permission for the
// site, reject.
if (antiTrackingRejectedReason ==
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION) {
promise->MaybeRejectWithUndefined();
return promise.forget();
}
// Note: If this has returned true, the top-level document is guaranteed // Note: If this has returned true, the top-level document is guaranteed
// to not be on the Content Blocking allow list. // to not be on the Content Blocking allow list.
MOZ_ASSERT(!CookieJarSettings()->GetIsOnContentBlockingAllowList()); MOZ_ASSERT(!CookieJarSettings()->GetIsOnContentBlockingAllowList());

View file

@ -139,7 +139,9 @@ nsCString ImageCacheKey::GetIsolationKey(Document* aDocument, nsIURI* aURI) {
// access is granted for this image. // access is granted for this image.
if (nsContentUtils::IsThirdPartyWindowOrChannel(aDocument->GetInnerWindow(), if (nsContentUtils::IsThirdPartyWindowOrChannel(aDocument->GetInnerWindow(),
nullptr, nullptr)) { nullptr, nullptr)) {
return StorageDisabledByAntiTracking(aDocument, aURI) uint32_t rejectedReason = 0;
Unused << rejectedReason;
return StorageDisabledByAntiTracking(aDocument, aURI, rejectedReason)
? aDocument->GetBaseDomain() ? aDocument->GetBaseDomain()
: ""_ns; : ""_ns;
} }

View file

@ -333,14 +333,15 @@ bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
return disabled; return disabled;
} }
bool StorageDisabledByAntiTracking(dom::Document* aDocument, nsIURI* aURI) { bool StorageDisabledByAntiTracking(dom::Document* aDocument, nsIURI* aURI,
uint32_t rejectedReason = 0; uint32_t& aRejectedReason) {
aRejectedReason = 0;
// Note that GetChannel() below may return null, but that's OK, since the // 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, // 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. // will only fail to notify the UI in case storage gets blocked.
return StorageDisabledByAntiTracking( return StorageDisabledByAntiTracking(
aDocument->GetInnerWindow(), aDocument->GetChannel(), aDocument->GetInnerWindow(), aDocument->GetChannel(),
aDocument->NodePrincipal(), aURI, rejectedReason); aDocument->NodePrincipal(), aURI, aRejectedReason);
} }
bool ShouldPartitionStorage(StorageAccess aAccess) { bool ShouldPartitionStorage(StorageAccess aAccess) {

View file

@ -102,7 +102,8 @@ bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
* Returns true if this document should disable storages because of the * Returns true if this document should disable storages because of the
* anti-tracking feature. * anti-tracking feature.
*/ */
bool StorageDisabledByAntiTracking(dom::Document* aDocument, nsIURI* aURI); bool StorageDisabledByAntiTracking(dom::Document* aDocument, nsIURI* aURI,
uint32_t& aRejectedReason);
bool ShouldPartitionStorage(StorageAccess aAccess); bool ShouldPartitionStorage(StorageAccess aAccess);

View file

@ -14,6 +14,13 @@ add_task(async _ => {
"cookie", "cookie",
Services.perms.ALLOW_ACTION Services.perms.ALLOW_ACTION
); );
// Grant interaction permission so we can directly call
// requestStorageAccess from the tracker.
PermissionTestUtils.add(
"https://tracking.example.org",
"storageAccessAPI",
Services.perms.ALLOW_ACTION
);
registerCleanupFunction(_ => { registerCleanupFunction(_ => {
Services.perms.removeAll(); Services.perms.removeAll();
@ -28,6 +35,19 @@ AntiTracking._createTask({
callback: async _ => { callback: async _ => {
document.cookie = "name=value"; document.cookie = "name=value";
ok(document.cookie != "", "Nothing is blocked"); ok(document.cookie != "", "Nothing is blocked");
// requestStorageAccess should resolve
let dwu = SpecialPowers.getDOMWindowUtils(window);
let helper = dwu.setHandlingUserInput(true);
await document
.requestStorageAccess()
.then(() => {
ok(true, "Should grant storage access");
})
.catch(() => {
ok(false, "Should grant storage access");
});
helper.destruct();
}, },
extraPrefs: null, extraPrefs: null,
expectedBlockingNotifications: 0, expectedBlockingNotifications: 0,

View file

@ -14,6 +14,13 @@ add_task(async _ => {
"cookie", "cookie",
Services.perms.DENY_ACTION Services.perms.DENY_ACTION
); );
// Grant interaction permission so we can directly call
// requestStorageAccess from the tracker.
PermissionTestUtils.add(
"https://tracking.example.org",
"storageAccessAPI",
Services.perms.ALLOW_ACTION
);
registerCleanupFunction(_ => { registerCleanupFunction(_ => {
Services.perms.removeAll(); Services.perms.removeAll();
@ -28,6 +35,19 @@ AntiTracking._createTask({
callback: async _ => { callback: async _ => {
document.cookie = "name=value"; document.cookie = "name=value";
ok(document.cookie == "", "All is blocked"); ok(document.cookie == "", "All is blocked");
// requestStorageAccess should reject
let dwu = SpecialPowers.getDOMWindowUtils(window);
let helper = dwu.setHandlingUserInput(true);
await document
.requestStorageAccess()
.then(() => {
ok(false, "Should not grant storage access");
})
.catch(() => {
ok(true, "Should not grant storage access");
});
helper.destruct();
}, },
extraPrefs: null, extraPrefs: null,
expectedBlockingNotifications: expectedBlockingNotifications: