зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 4 changesets (bug 1507769, bug 1505571) for browser_storageAccessWithHeuristics.js failures CLOSED TREE
Backed out changeset 401763b97e54 (bug 1507769) Backed out changeset 838dfe679fdd (bug 1505571) Backed out changeset 88af3329ee16 (bug 1505571) Backed out changeset be17a8b7aefa (bug 1505571)
This commit is contained in:
Родитель
70b7e86a2b
Коммит
97ae4101ac
|
@ -12903,7 +12903,7 @@ nsIDocument::SetUserHasInteracted()
|
|||
loadInfo->SetDocumentHasUserInteracted(true);
|
||||
}
|
||||
|
||||
MaybeAllowStorageForOpenerAfterUserInteraction();
|
||||
MaybeAllowStorageForOpener();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -12950,7 +12950,7 @@ nsIDocument::SetDocTreeHadPlayRevoked()
|
|||
}
|
||||
|
||||
void
|
||||
nsIDocument::MaybeAllowStorageForOpenerAfterUserInteraction()
|
||||
nsIDocument::MaybeAllowStorageForOpener()
|
||||
{
|
||||
if (StaticPrefs::network_cookie_cookieBehavior() !=
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
|
||||
|
@ -13008,7 +13008,7 @@ nsIDocument::MaybeAllowStorageForOpenerAfterUserInteraction()
|
|||
// We don't care when the asynchronous work finishes here.
|
||||
Unused << AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(NodePrincipal(),
|
||||
openerInner,
|
||||
AntiTrackingCommon::eOpenerAfterUserInteraction);
|
||||
AntiTrackingCommon::eHeuristic);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -8067,20 +8067,6 @@ nsPIDOMWindowInner::GetAutoplayPermissionManager()
|
|||
return manager.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsPIDOMWindowInner::SaveStorageAccessGranted(const nsACString& aPermissionKey)
|
||||
{
|
||||
if (!HasStorageAccessGranted(aPermissionKey)) {
|
||||
mStorageAccessGranted.AppendElement(aPermissionKey);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsPIDOMWindowInner::HasStorageAccessGranted(const nsACString& aPermissionKey)
|
||||
{
|
||||
return mStorageAccessGranted.Contains(aPermissionKey);
|
||||
}
|
||||
|
||||
// XXX: Can we define this in a header instead of here?
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
|
|
@ -7236,7 +7236,7 @@ nsGlobalWindowOuter::MaybeAllowStorageForOpenedWindow(nsIURI* aURI)
|
|||
// We don't care when the asynchronous work finishes here.
|
||||
Unused << AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(principal,
|
||||
inner,
|
||||
AntiTrackingCommon::eOpener);
|
||||
AntiTrackingCommon::eHeuristic);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
|
|
@ -3982,7 +3982,7 @@ protected:
|
|||
// Return the same type parent docuement if exists, or return null.
|
||||
nsIDocument* GetSameTypeParentDocument();
|
||||
|
||||
void MaybeAllowStorageForOpenerAfterUserInteraction();
|
||||
void MaybeAllowStorageForOpener();
|
||||
|
||||
void MaybeStoreUserInteractionAsPermission();
|
||||
|
||||
|
|
|
@ -646,12 +646,6 @@ public:
|
|||
void
|
||||
NotifyReportingObservers();
|
||||
|
||||
void
|
||||
SaveStorageAccessGranted(const nsACString& aPermissionKey);
|
||||
|
||||
bool
|
||||
HasStorageAccessGranted(const nsACString& aPermissionKey);
|
||||
|
||||
protected:
|
||||
void CreatePerformanceObjectIfNeeded();
|
||||
|
||||
|
@ -750,11 +744,6 @@ protected:
|
|||
// List of Report objects for ReportingObservers.
|
||||
nsTArray<RefPtr<mozilla::dom::ReportingObserver>> mReportingObservers;
|
||||
nsTArray<RefPtr<mozilla::dom::Report>> mReportRecords;
|
||||
|
||||
// This is a list of storage access granted for the current window. These are
|
||||
// also set as permissions, but it could happen that we need to access them
|
||||
// synchronously in this context, and for this, we need a copy here.
|
||||
nsTArray<nsCString> mStorageAccessGranted;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)
|
||||
|
|
|
@ -1375,10 +1375,6 @@ pref("privacy.popups.disable_from_plugins", 3);
|
|||
// Enable Paritioned LocalStorage for a list of hosts.
|
||||
pref("privacy.restrict3rdpartystorage.partitionedHosts", "accounts.google.com/o/oauth2/");
|
||||
|
||||
// If a host is contained in this pref list, user-interaction is required
|
||||
// before granting the storage access permission.
|
||||
pref("privacy.restrict3rdpartystorage.userInteractionRequiredForHosts", "");
|
||||
|
||||
// Excessive reporting of blocked popups can be a DOS vector,
|
||||
// by overloading the main process as popups get blocked and when
|
||||
// users try to restore all popups, which is the most visible
|
||||
|
|
|
@ -332,9 +332,7 @@ ReportUnblockingConsole(nsPIDOMWindowInner* aWindow,
|
|||
messageWithSameOrigin = "CookieAllowedForTrackerByStorageAccessAPI";
|
||||
break;
|
||||
|
||||
case AntiTrackingCommon::eOpenerAfterUserInteraction:
|
||||
MOZ_FALLTHROUGH;
|
||||
case AntiTrackingCommon::eOpener:
|
||||
case AntiTrackingCommon::eHeuristic:
|
||||
messageWithDifferentOrigin = "CookieAllowedForOriginOnTrackerByHeuristic";
|
||||
messageWithSameOrigin = "CookieAllowedForTrackerByHeuristic";
|
||||
break;
|
||||
|
@ -489,31 +487,10 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(nsIPrincipal* aPrincipa
|
|||
return StorageAccessGrantPromise::CreateAndReject(false, __func__);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> topOuterWindow = outerParentWindow->GetTop();
|
||||
nsGlobalWindowOuter* topWindow = nsGlobalWindowOuter::Cast(topOuterWindow);
|
||||
if (NS_WARN_IF(!topWindow)) {
|
||||
LOG(("No top outer window."));
|
||||
return StorageAccessGrantPromise::CreateAndReject(false, __func__);
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* topInnerWindow = topWindow->GetCurrentInnerWindow();
|
||||
if (NS_WARN_IF(!topInnerWindow)) {
|
||||
LOG(("No top inner window."));
|
||||
return StorageAccessGrantPromise::CreateAndReject(false, __func__);
|
||||
}
|
||||
|
||||
// We hardcode this block reason since the first-party storage access
|
||||
// permission is granted for the purpose of blocking trackers.
|
||||
// Note that if aReason is eOpenerAfterUserInteraction and the
|
||||
// trackingPrincipal is not in a blacklist, we don't check the
|
||||
// user-interaction state, because it could be that the current process has
|
||||
// just sent the request to store the user-interaction permission into the
|
||||
// parent, without having received the permission itself yet.
|
||||
// We hardcode this block reason since the first-party storage access permission
|
||||
// is granted for the purpose of blocking trackers.
|
||||
const uint32_t blockReason = nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER;
|
||||
if ((aReason != eOpenerAfterUserInteraction ||
|
||||
nsContentUtils::IsURIInPrefList(trackingURI,
|
||||
"privacy.restrict3rdpartystorage.userInteractionRequiredForHosts")) &&
|
||||
!HasUserInteraction(trackingPrincipal)) {
|
||||
if (!HasUserInteraction(trackingPrincipal)) {
|
||||
LOG_SPEC(("Tracking principal (%s) hasn't been interacted with before, "
|
||||
"refusing to add a first-party storage permission to access it",
|
||||
_spec), trackingURI);
|
||||
|
@ -527,19 +504,13 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(nsIPrincipal* aPrincipa
|
|||
return StorageAccessGrantPromise::CreateAndReject(false, __func__);
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 grantedOrigin(origin);
|
||||
|
||||
nsAutoCString permissionKey;
|
||||
CreatePermissionKey(trackingOrigin, grantedOrigin, permissionKey);
|
||||
|
||||
// Let's store the permission in the current parent window.
|
||||
topInnerWindow->SaveStorageAccessGranted(permissionKey);
|
||||
|
||||
nsIChannel* channel =
|
||||
pwin->GetCurrentInnerWindow()->GetExtantDoc()->GetChannel();
|
||||
|
||||
pwin->NotifyContentBlockingState(blockReason, channel, false, trackingURI);
|
||||
|
||||
NS_ConvertUTF16toUTF8 grantedOrigin(origin);
|
||||
|
||||
ReportUnblockingConsole(parentWindow, NS_ConvertUTF8toUTF16(trackingOrigin),
|
||||
origin, aReason);
|
||||
|
||||
|
@ -623,7 +594,7 @@ AntiTrackingCommon::SaveFirstPartyStorageAccessGrantedForOriginOnParentProcess(n
|
|||
nsAutoCString type;
|
||||
CreatePermissionKey(aTrackingOrigin, aGrantedOrigin, type);
|
||||
|
||||
LOG(("Computed permission key: %s, expiry: %u, proceeding to save in the permission manager",
|
||||
LOG(("Computed permission key: %s, expiry: %d, proceeding to save in the permission manager",
|
||||
type.get(), expirationTime));
|
||||
|
||||
rv = pm->AddFromPrincipal(aParentPrincipal, type.get(),
|
||||
|
@ -797,35 +768,8 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aWin
|
|||
return false;
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 grantedOrigin(origin);
|
||||
|
||||
nsGlobalWindowOuter* outerWindow =
|
||||
nsGlobalWindowOuter::Cast(aWindow->GetOuterWindow());
|
||||
if (NS_WARN_IF(!outerWindow)) {
|
||||
LOG(("No outer window."));
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> topOuterWindow = outerWindow->GetTop();
|
||||
nsGlobalWindowOuter* topWindow = nsGlobalWindowOuter::Cast(topOuterWindow);
|
||||
if (NS_WARN_IF(!topWindow)) {
|
||||
LOG(("No top outer window."));
|
||||
return false;
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* topInnerWindow = topWindow->GetCurrentInnerWindow();
|
||||
if (NS_WARN_IF(!topInnerWindow)) {
|
||||
LOG(("No top inner window."));
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoCString type;
|
||||
CreatePermissionKey(trackingOrigin, grantedOrigin, type);
|
||||
|
||||
if (topInnerWindow->HasStorageAccessGranted(type)) {
|
||||
LOG(("Permission stored in the window. All good."));
|
||||
return true;
|
||||
}
|
||||
CreatePermissionKey(trackingOrigin, NS_ConvertUTF16toUTF8(origin), type);
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> pm = services::GetPermissionManager();
|
||||
if (NS_WARN_IF(!pm)) {
|
||||
|
|
|
@ -74,8 +74,7 @@ public:
|
|||
enum StorageAccessGrantedReason
|
||||
{
|
||||
eStorageAccessAPI,
|
||||
eOpenerAfterUserInteraction,
|
||||
eOpener
|
||||
eHeuristic,
|
||||
};
|
||||
|
||||
// Grant the permission for aOrigin to have access to the first party storage.
|
||||
|
|
|
@ -60,8 +60,6 @@ skip-if = serviceworker_e10s
|
|||
[browser_storageAccessWithHeuristics.js]
|
||||
[browser_allowPermissionForTracker.js]
|
||||
[browser_denyPermissionForTracker.js]
|
||||
[browser_localStorageEvents.js]
|
||||
support-files = localStorage.html
|
||||
[browser_partitionedLocalStorage.js]
|
||||
[browser_partitionedLocalStorage_events.js]
|
||||
support-files = localStorageEvents.html
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
add_task(async function() {
|
||||
info("Starting subResources test");
|
||||
|
||||
await SpecialPowers.flushPrefEnv();
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.storage_access.enabled", true],
|
||||
["browser.contentblocking.allowlist.annotations.enabled", true],
|
||||
["browser.contentblocking.allowlist.storage.enabled", true],
|
||||
["browser.fastblock.enabled", false],
|
||||
["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER],
|
||||
["privacy.trackingprotection.enabled", false],
|
||||
["privacy.trackingprotection.pbmode.enabled", false],
|
||||
["privacy.trackingprotection.annotate_channels", true],
|
||||
]});
|
||||
|
||||
await UrlClassifierTestUtils.addTestTrackers();
|
||||
});
|
||||
|
||||
add_task(async function testLocalStorageEventPropagation() {
|
||||
info("Creating a new tab");
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
info("Loading tracking scripts");
|
||||
await ContentTask.spawn(browser, {
|
||||
page: TEST_3RD_PARTY_DOMAIN + TEST_PATH + "localStorage.html",
|
||||
}, async obj => {
|
||||
info("Creating tracker iframe");
|
||||
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.src = obj.page;
|
||||
|
||||
await new content.Promise(resolve => {
|
||||
ifr.onload = function() {
|
||||
resolve();
|
||||
};
|
||||
content.document.body.appendChild(ifr);
|
||||
});
|
||||
|
||||
info("LocalStorage should be blocked.");
|
||||
await new content.Promise(resolve => {
|
||||
content.addEventListener("message", e => {
|
||||
if (e.data.type == "test") {
|
||||
is(e.data.status, false, "LocalStorage blocked");
|
||||
} else {
|
||||
ok(false, "Unknown message");
|
||||
}
|
||||
resolve();
|
||||
}, {once: true});
|
||||
ifr.contentWindow.postMessage("test", "*");
|
||||
});
|
||||
|
||||
info("Let's open the popup");
|
||||
await new content.Promise(resolve => {
|
||||
content.addEventListener("message", e => {
|
||||
if (e.data.type == "test") {
|
||||
is(e.data.status, true, "LocalStorage unblocked");
|
||||
} else {
|
||||
ok(false, "Unknown message");
|
||||
}
|
||||
resolve();
|
||||
}, {once: true});
|
||||
ifr.contentWindow.postMessage("open", "*");
|
||||
});
|
||||
});
|
||||
|
||||
info("Removing the tab");
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
||||
info("Cleaning up.");
|
||||
await new Promise(resolve => {
|
||||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function testBlockedLocalStorageEventPropagation() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["privacy.restrict3rdpartystorage.userInteractionRequiredForHosts", "tracking.example.com,tracking.example.org"],
|
||||
]});
|
||||
|
||||
info("Creating a new tab");
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
info("Loading tracking scripts");
|
||||
await ContentTask.spawn(browser, {
|
||||
page: TEST_3RD_PARTY_DOMAIN + TEST_PATH + "localStorage.html",
|
||||
}, async obj => {
|
||||
info("Creating tracker iframe");
|
||||
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.src = obj.page;
|
||||
|
||||
await new content.Promise(resolve => {
|
||||
ifr.onload = function() {
|
||||
resolve();
|
||||
};
|
||||
content.document.body.appendChild(ifr);
|
||||
});
|
||||
|
||||
info("LocalStorage should be blocked.");
|
||||
await new content.Promise(resolve => {
|
||||
content.addEventListener("message", e => {
|
||||
if (e.data.type == "test") {
|
||||
is(e.data.status, false, "LocalStorage blocked");
|
||||
} else {
|
||||
ok(false, "Unknown message");
|
||||
}
|
||||
resolve();
|
||||
}, {once: true});
|
||||
ifr.contentWindow.postMessage("test", "*");
|
||||
});
|
||||
|
||||
info("Let's open the popup");
|
||||
await new content.Promise(resolve => {
|
||||
content.addEventListener("message", e => {
|
||||
if (e.data.type == "test") {
|
||||
is(e.data.status, false, "LocalStorage still blocked");
|
||||
} else {
|
||||
ok(false, "Unknown message");
|
||||
}
|
||||
resolve();
|
||||
}, {once: true});
|
||||
ifr.contentWindow.postMessage("open and test", "*");
|
||||
});
|
||||
});
|
||||
|
||||
info("Removing the tab");
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
||||
info("Cleaning up.");
|
||||
await new Promise(resolve => {
|
||||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||
});
|
||||
});
|
|
@ -255,7 +255,6 @@ this.AntiTracking = {
|
|||
["privacy.trackingprotection.annotate_channels", cookieBehavior != BEHAVIOR_ACCEPT],
|
||||
[win.ContentBlocking.prefIntroCount, win.ContentBlocking.MAX_INTROS],
|
||||
["browser.fastblock.enabled", false], // prevent intermittent failures
|
||||
["privacy.restrict3rdpartystorage.userInteractionRequiredForHosts", "tracking.example.com,tracking.example.org"],
|
||||
]});
|
||||
|
||||
if (extraPrefs && Array.isArray(extraPrefs) && extraPrefs.length) {
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
<h1>Here a tracker!</h1>
|
||||
<script>
|
||||
|
||||
if (window.opener) {
|
||||
SpecialPowers.wrap(document).userInteractionForTesting();
|
||||
localStorage.foo = "opener" + Math.random();
|
||||
window.close();
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
window.onmessage = e => {
|
||||
if (e.data == "test") {
|
||||
let status;
|
||||
try {
|
||||
localStorage.foo = "value" + Math.random();
|
||||
status = true;
|
||||
} catch (e) {
|
||||
status = false;
|
||||
}
|
||||
|
||||
parent.postMessage({type: "test", status }, "*");
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.data == "open") {
|
||||
window.open("localStorage.html");
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.data == "open and test") {
|
||||
let w = window.open("localStorage.html");
|
||||
w.addEventListener("load", _ => {
|
||||
let status;
|
||||
try {
|
||||
localStorage.foo = "value" + Math.random();
|
||||
status = true;
|
||||
} catch (e) {
|
||||
status = false;
|
||||
}
|
||||
|
||||
parent.postMessage({type: "test", status }, "*");
|
||||
}, {once: true});
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("storage", e => {
|
||||
let fromOpener = localStorage.foo.startsWith("opener");
|
||||
|
||||
let status;
|
||||
try {
|
||||
localStorage.foo = "value" + Math.random();
|
||||
status = true;
|
||||
} catch (e) {
|
||||
status = false;
|
||||
}
|
||||
|
||||
parent.postMessage({type: "test", status: status && fromOpener }, "*");
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче