зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1507769 - User-interaction required before granting storage access for some 3rd party trackers, r=ehsan
We want to introduce a new pref to block trackers that try to workaround our heuristic. The pref is called: privacy.restrict3rdpartystorage.userInteractionRequiredForHosts
This commit is contained in:
Родитель
f8679dfb52
Коммит
7fd5fc4b5c
|
@ -1375,6 +1375,10 @@ 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
|
||||
|
|
|
@ -504,12 +504,15 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(nsIPrincipal* aPrincipa
|
|||
|
||||
// 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, we don't check the
|
||||
// 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.
|
||||
const uint32_t blockReason = nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER;
|
||||
if (aReason != eOpenerAfterUserInteraction &&
|
||||
if ((aReason != eOpenerAfterUserInteraction ||
|
||||
nsContentUtils::IsURIInPrefList(trackingURI,
|
||||
"privacy.restrict3rdpartystorage.userInteractionRequiredForHosts")) &&
|
||||
!HasUserInteraction(trackingPrincipal)) {
|
||||
LOG_SPEC(("Tracking principal (%s) hasn't been interacted with before, "
|
||||
"refusing to add a first-party storage permission to access it",
|
||||
|
|
|
@ -71,9 +71,71 @@ add_task(async function testLocalStorageEventPropagation() {
|
|||
|
||||
info("Removing the tab");
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function() {
|
||||
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,6 +255,7 @@ 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) {
|
||||
|
|
|
@ -24,6 +24,22 @@ if (parent) {
|
|||
|
||||
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});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче