Bug 1798407 - Restrict Storage Access API usage to within secure contexts. Set the Static Pref to pass all tests which use insecure contexts. r=bvandersloot,anti-tracking-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D182366
This commit is contained in:
Harshit Sohaney 2023-08-02 15:58:23 +00:00
Родитель 1c9c1d602d
Коммит 54d2807125
9 изменённых файлов: 162 добавлений и 31 удалений

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

@ -416,6 +416,8 @@ RequestStorageAccessNested=document.requestStorageAccess() may not be called in
RequestStorageAccessUserGesture=document.requestStorageAccess() may only be requested from inside a short running user-generated event handler.
# LOCALIZATION NOTE: Do not translate document.requestStorageAccess(), Permissions Policy and storage-access.
RequestStorageAccessPermissionsPolicy=document.requestStorageAccess() may not be called where the storage-access feature is blocked by the Permissions Policy.
# LOCALIZATION NOTE: Do not translate document.requestStorageAccess()
RequestStorageAccessNotSecureContext=document.requestStorageAccess() may only grant access to secure contexts.
# LOCALIZATION NOTE: Do not translate "Location" and "History".
LocChangeFloodingPrevented=Too many calls to Location or History APIs within a short timeframe.
FolderUploadPrompt.title = Confirm Upload

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

@ -4019,6 +4019,12 @@
value: false
mirror: always
# Only grant storage access to secure contexts.
- name: dom.storage_access.dont_grant_insecure_contexts
type: RelaxedAtomicBool
value: true
mirror: always
# Whether the Storage API is enabled.
- name: dom.storageManager.enabled
type: RelaxedAtomicBool

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

@ -16,3 +16,9 @@ user_pref("nglayout.initialpaint.unsuppress_with_no_background", true);
// Disable prefers-reduced-motion to ensure that smooth scrolls can be tested.
user_pref("general.smoothScroll", true);
// Disable secure context pref for testing storage access API.
// Related Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1840902.
// Plan to remove this pref since all tests must be compliant with the
// storage access API spec for secure contexts.
user_pref("dom.storage_access.dont_grant_insecure_contexts", false);

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

@ -913,6 +913,25 @@ Maybe<bool> StorageAccessAPIHelper::CheckCallingContextDecidesStorageAccessAPI(
}
}
// Check if NodePrincipal is not null
if (!aDocument->NodePrincipal()) {
return Some(false);
}
// If the document doesn't have a secure context, reject. The Static Pref is
// used to pass existing tests that do not fulfil this check.
if (StaticPrefs::dom_storage_access_dont_grant_insecure_contexts() &&
!aDocument->NodePrincipal()->GetIsOriginPotentiallyTrustworthy()) {
// Report the error to the console if we are requesting access
if (aRequestingStorageAccess) {
nsContentUtils::ReportToConsole(
nsIScriptError::errorFlag, nsLiteralCString("requestStorageAccess"),
aDocument, nsContentUtils::eDOM_PROPERTIES,
"RequestStorageAccessNotSecureContext");
}
return Some(false);
}
// If the document has a null origin, reject.
if (aDocument->NodePrincipal()->GetIsNullPrincipal()) {
// Report an error to the console for this case if we are requesting access

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

@ -95,6 +95,7 @@ skip-if =
[browser_referrerDefaultPolicy.js]
support-files = referrer.sjs
[browser_siteSpecificWorkArounds.js]
[browser_storageAccessRejectsInsecureContexts.js]
[browser_subResources.js]
support-files = subResources.sjs
[browser_subResourcesPartitioned.js]

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

@ -1,3 +1,5 @@
/* import-globals-from antitracking_head.js */
// This test ensures HasStorageAccess API returns the right value under different
// scenarios.
@ -5,25 +7,31 @@ var settings = [
// same-origin no-tracker
{
name: "Test whether same-origin non-tracker frame has storage access",
topPage: TEST_TOP_PAGE,
thirdPartyPage: TEST_DOMAIN + TEST_PATH + "3rdParty.html",
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_DOMAIN_HTTPS + TEST_PATH + "3rdParty.html",
},
// 3rd-party no-tracker
{
name: "Test whether 3rd-party non-tracker frame has storage access",
topPage: TEST_TOP_PAGE,
thirdPartyPage: TEST_4TH_PARTY_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_4TH_PARTY_PAGE_HTTPS,
},
// 3rd-party no-tracker with permission
{
name: "Test whether 3rd-party non-tracker frame has storage access when storage permission is granted before",
topPage: TEST_TOP_PAGE,
thirdPartyPage: TEST_4TH_PARTY_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_4TH_PARTY_PAGE_HTTPS,
setup: () => {
let type = "3rdPartyFrameStorage^http://example.com";
let type = "3rdPartyStorage^https://not-tracking.example.com";
let permission = Services.perms.ALLOW_ACTION;
let expireType = Services.perms.EXPIRE_SESSION;
PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0);
PermissionTestUtils.add(
TEST_DOMAIN_HTTPS,
type,
permission,
expireType,
0
);
registerCleanupFunction(_ => {
Services.perms.removeAll();
@ -33,19 +41,25 @@ var settings = [
// 3rd-party tracker
{
name: "Test whether 3rd-party tracker frame has storage access",
topPage: TEST_TOP_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_3RD_PARTY_PAGE,
},
// 3rd-party tracker with permission
{
name: "Test whether 3rd-party tracker frame has storage access when storage access permission is granted before",
topPage: TEST_TOP_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_3RD_PARTY_PAGE,
setup: () => {
let type = "3rdPartyFrameStorage^https://example.org";
let permission = Services.perms.ALLOW_ACTION;
let expireType = Services.perms.EXPIRE_SESSION;
PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0);
PermissionTestUtils.add(
TEST_DOMAIN_HTTPS,
type,
permission,
expireType,
0
);
registerCleanupFunction(_ => {
Services.perms.removeAll();
@ -55,14 +69,20 @@ var settings = [
// same-site 3rd-party tracker
{
name: "Test whether same-site 3rd-party tracker frame has storage access",
topPage: TEST_TOP_PAGE,
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE_HTTPS,
},
// same-origin 3rd-party tracker
{
name: "Test whether same-origin 3rd-party tracker frame has storage access",
topPage: TEST_ANOTHER_3RD_PARTY_DOMAIN + TEST_PATH + "page.html",
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE,
topPage: TEST_ANOTHER_3RD_PARTY_DOMAIN_HTTPS + TEST_PATH + "page.html",
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE_HTTPS,
},
// Insecure 3rd-party tracker
{
name: "Test whether insecure 3rd-party tracker frame has storage access",
topPage: TEST_TOP_PAGE + TEST_PATH + "page.html",
thirdPartyPage: TEST_3RD_PARTY_PAGE_HTTP,
},
];
@ -77,6 +97,7 @@ var testCases = [
true /* 3rd-party tracker with permission */,
true /* same-site tracker */,
true /* same-origin tracker */,
true /* Insecure context */,
],
},
{
@ -93,6 +114,7 @@ var testCases = [
) /* 3rd-party non-tracker with permission */,
true /* same-site tracker */,
true /* same-origin tracker */,
false /* Insecure context */,
],
},
{
@ -105,6 +127,7 @@ var testCases = [
false /* 3rd-party tracker with permission */,
false /* same-site tracker */,
false /* same-origin tracker */,
false /* Insecure context */,
],
},
{
@ -117,6 +140,7 @@ var testCases = [
false /* 3rd-party tracker with permission */,
true /* same-site tracker */,
true /* same-origin tracker */,
false /* Insecure context */,
],
},
{
@ -129,6 +153,7 @@ var testCases = [
true /* 3rd-party tracker with permission */,
true /* same-site tracker */,
true /* same-origin tracker */,
false /* Insecure context */,
],
},
{
@ -141,6 +166,7 @@ var testCases = [
true /* 3rd-party tracker with permission */,
true /* same-site tracker */,
true /* same-origin tracker */,
false /* Insecure context */,
],
},
];
@ -174,6 +200,8 @@ var testCases = [
"privacy.partition.always_partition_third_party_non_cookie_storage",
false,
],
// Testing Storage Access API grants constrained to secure contexts
["dom.storage_access.dont_grant_insecure_contexts", true],
],
expectedBlockingNotifications: 0,
runInPrivateWindow: false,

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

@ -1,3 +1,5 @@
/* import-globals-from antitracking_head.js */
// This test ensures HasStorageAccess API returns the right value under different
// scenarios.
@ -5,25 +7,31 @@ var settings = [
// same-origin no-tracker
{
name: "Test whether same-origin non-tracker frame has storage access",
topPage: TEST_TOP_PAGE,
thirdPartyPage: TEST_DOMAIN + TEST_PATH + "3rdParty.html",
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_DOMAIN_HTTPS + TEST_PATH + "3rdParty.html",
},
// 3rd-party no-tracker
{
name: "Test whether 3rd-party non-tracker frame has storage access",
topPage: TEST_TOP_PAGE,
thirdPartyPage: TEST_4TH_PARTY_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_4TH_PARTY_PAGE_HTTPS,
},
// 3rd-party no-tracker with permission
{
name: "Test whether 3rd-party non-tracker frame has storage access when storage permission is granted before",
topPage: TEST_TOP_PAGE,
thirdPartyPage: TEST_4TH_PARTY_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_4TH_PARTY_PAGE_HTTPS,
setup: () => {
let type = "3rdPartyFrameStorage^http://example.com";
let type = "3rdPartyStorage^https://not-tracking.example.com";
let permission = Services.perms.ALLOW_ACTION;
let expireType = Services.perms.EXPIRE_SESSION;
PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0);
PermissionTestUtils.add(
TEST_DOMAIN_HTTPS,
type,
permission,
expireType,
0
);
registerCleanupFunction(_ => {
Services.perms.removeAll();
@ -33,19 +41,25 @@ var settings = [
// 3rd-party tracker
{
name: "Test whether 3rd-party tracker frame has storage access",
topPage: TEST_TOP_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_3RD_PARTY_PAGE,
},
// 3rd-party tracker with permission
{
name: "Test whether 3rd-party tracker frame has storage access when storage access permission is granted before",
topPage: TEST_TOP_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_3RD_PARTY_PAGE,
setup: () => {
let type = "3rdPartyFrameStorage^https://example.org";
let permission = Services.perms.ALLOW_ACTION;
let expireType = Services.perms.EXPIRE_SESSION;
PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0);
PermissionTestUtils.add(
TEST_DOMAIN_HTTPS,
type,
permission,
expireType,
0
);
registerCleanupFunction(_ => {
Services.perms.removeAll();
@ -55,14 +69,20 @@ var settings = [
// same-site 3rd-party tracker
{
name: "Test whether same-site 3rd-party tracker frame has storage access",
topPage: TEST_TOP_PAGE,
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE,
topPage: TEST_TOP_PAGE_HTTPS,
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE_HTTPS,
},
// same-origin 3rd-party tracker
{
name: "Test whether same-origin 3rd-party tracker frame has storage access",
topPage: TEST_ANOTHER_3RD_PARTY_DOMAIN + TEST_PATH + "page.html",
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE,
topPage: TEST_ANOTHER_3RD_PARTY_DOMAIN_HTTPS + TEST_PATH + "page.html",
thirdPartyPage: TEST_ANOTHER_3RD_PARTY_PAGE_HTTPS,
},
// Insecure 3rd-party tracker
{
name: "Test whether insecure 3rd-party tracker frame has storage access",
topPage: TEST_TOP_PAGE + TEST_PATH + "page.html",
thirdPartyPage: TEST_3RD_PARTY_PAGE_HTTP,
},
];
@ -81,6 +101,7 @@ var testCases = [
[true] /* 3rd-party tracker with permission */,
[true] /* same-site tracker */,
[true] /* same-origin tracker */,
[true] /* insecure tracker */,
],
},
{
@ -103,6 +124,7 @@ var testCases = [
] /* 3rd-party non-tracker with permission */,
[true] /* same-site tracker */,
[true] /* same-origin tracker */,
[false, foreignBlocked] /* insecure tracker */,
],
},
{
@ -115,6 +137,7 @@ var testCases = [
[false, allBlocked] /* 3rd-party tracker with permission */,
[false, allBlocked] /* same-site tracker */,
[false, allBlocked] /* same-origin tracker */,
[false, allBlocked] /* insecure tracker */,
],
},
{
@ -127,6 +150,7 @@ var testCases = [
[false, foreignBlocked] /* 3rd-party tracker with permission */,
[true] /* same-site tracker */,
[true] /* same-origin tracker */,
[false, foreignBlocked] /* insecure tracker */,
],
},
{
@ -139,6 +163,7 @@ var testCases = [
[true] /* 3rd-party tracker with permission */,
[true] /* same-site tracker */,
[true] /* same-origin tracker */,
[false, trackerBlocked] /* insecure tracker */,
],
},
{
@ -151,6 +176,7 @@ var testCases = [
[true] /* 3rd-party tracker with permission */,
[true] /* same-site tracker */,
[true] /* same-origin tracker */,
[false, trackerBlocked] /* insecure tracker */,
],
},
];
@ -187,6 +213,8 @@ var testCases = [
"privacy.partition.always_partition_third_party_non_cookie_storage",
true,
],
// Testing Storage Access API grants constrained to secure contexts
["dom.storage_access.dont_grant_insecure_contexts", true],
],
expectedBlockingNotifications,
runInPrivateWindow: false,

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

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/browser/modules/test/browser/head.js",
this
);
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/toolkit/components/antitracking/test/browser/storage_access_head.js",
this
);
add_task(async function testInsecureContext() {
await SpecialPowers.pushPrefEnv({
set: [["dom.storage_access.dont_grant_insecure_contexts", true]],
});
await setPreferences();
await openPageAndRunCode(
TEST_TOP_PAGE_HTTPS,
getExpectPopupAndClick("accept"),
TEST_3RD_PARTY_PAGE,
requestStorageAccessAndExpectSuccess
);
await openPageAndRunCode(
TEST_TOP_PAGE,
expectNoPopup,
TEST_3RD_PARTY_PAGE_HTTP,
requestStorageAccessAndExpectFailure
);
await cleanUpData();
await SpecialPowers.flushPrefEnv();
});

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

@ -55,6 +55,8 @@ const TEST_3RD_PARTY_PAGE_WITH_SVG =
const TEST_3RD_PARTY_PAGE_RELAY =
TEST_4TH_PARTY_DOMAIN + TEST_PATH + "3rdPartyRelay.html";
const TEST_4TH_PARTY_PAGE = TEST_4TH_PARTY_DOMAIN + TEST_PATH + "3rdParty.html";
const TEST_4TH_PARTY_PAGE_HTTPS =
TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "3rdParty.html";
const TEST_ANOTHER_3RD_PARTY_PAGE =
TEST_ANOTHER_3RD_PARTY_DOMAIN + TEST_PATH + "3rdParty.html";
const TEST_ANOTHER_3RD_PARTY_PAGE_HTTPS =
@ -71,7 +73,8 @@ const TEST_4TH_PARTY_STORAGE_PAGE_HTTPS =
TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "3rdPartyStorage.html";
const TEST_4TH_PARTY_PARTITIONED_PAGE =
TEST_4TH_PARTY_DOMAIN + TEST_PATH + "3rdPartyPartitioned.html";
const TEST_4TH_PARTY_PARTITIONED_PAGE_HTTPS =
TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "3rdPartyPartitioned.html";
const BEHAVIOR_ACCEPT = Ci.nsICookieService.BEHAVIOR_ACCEPT;
const BEHAVIOR_REJECT = Ci.nsICookieService.BEHAVIOR_REJECT;
const BEHAVIOR_LIMIT_FOREIGN = Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN;