Bug 1483765 - Fix the image cache key computation logic to only consider first-party storage access for third-party windows; r=smaug

This commit is contained in:
Ehsan Akhgari 2018-08-16 16:44:37 -04:00
parent a930263192
commit 4ab27b1e45
5 changed files with 89 additions and 7 deletions

View File

@ -130,7 +130,10 @@ ImageCacheKey::SchemeIs(const char* aScheme)
/* static */ void*
ImageCacheKey::GetSpecialCaseDocumentToken(nsIDocument* aDocument, nsIURI* aURI)
{
if (!aDocument) {
// Cookie-averse documents can never have storage granted to them. Since they
// may not have inner windows, they would require special handling below, so
// just bail out early here.
if (!aDocument || aDocument->IsCookieAverse()) {
return nullptr;
}
@ -141,10 +144,11 @@ ImageCacheKey::GetSpecialCaseDocumentToken(nsIDocument* aDocument, nsIURI* aURI)
return aDocument;
}
// If we must disable the storage, we want to create a unique cache key for
// this image.
if (nsContentUtils::StorageDisabledByAntiTracking(aDocument, aURI)) {
return aDocument;
// If the window is 3rd party resource, let's see if first-party storage
// access is granted for this image.
if (nsContentUtils::IsTrackingResourceWindow(aDocument->GetInnerWindow())) {
return nsContentUtils::StorageDisabledByAntiTracking(aDocument, aURI) ?
aDocument : nullptr;
}
// Another scenario is if this image is a 3rd party resource loaded by a
@ -153,8 +157,7 @@ ImageCacheKey::GetSpecialCaseDocumentToken(nsIDocument* aDocument, nsIURI* aURI)
// this point. The best approach here is to be conservative: if we are sure
// that the permission is granted, let's return a nullptr. Otherwise, let's
// make a unique image cache.
if (!aDocument->IsCookieAverse() &&
!AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(aDocument->GetInnerWindow(),
if (!AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(aDocument->GetInnerWindow(),
aURI)) {
return aDocument;
}

View File

@ -0,0 +1,20 @@
<html>
<head>
<title>3rd party content!</title>
<style>
body {
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path fill="context-fill" d="M28.5,8.1c0-1.1-1-1.9-2.1-2.4V3.7c-0.2-0.2-0.3-0.3-0.6-0.3c-0.6,0-1.1,0.8-1.3,2.1c-0.2,0-0.3,0-0.5,0l0,0c0-0.2,0-0.3-0.2-0.5c-0.3-1.1-0.8-1.9-1.3-2.6C22,2.6,21.7,3.2,21.7,4L22,6.3c-0.3,0.2-0.6,0.3-1,0.6l-3.5,3.7l0,0c0,0-6.3-0.8-10.9,0.2c-0.6,0-1,0.2-1.1,0.3c-0.5,0.2-0.8,0.3-1.1,0.6c-1.1-0.8-2.2-2.1-3.2-4c0-0.3-0.5-0.5-0.8-0.5s-0.5,0.6-0.3,1c0.8,2.1,2.1,3.5,3.4,4.5c-0.5,0.5-0.8,1-1,1.6c0,0-0.3,2.2-0.3,5.5l1.4,8c0,1,0.8,1.8,1.9,1.8c1,0,1.9-0.8,1.9-1.8V23l0.5-1.3h8.8l0.8,1.3v4.7c0,1,0.8,1.8,1.9,1.8c1,0,1.6-0.6,1.8-1.4l0,0l1.9-9l0,0l2.1-6.4h3c3.4,0,3.7-2.9,3.7-2.9L28.5,8.1z"/></svg>');
}
</style>
</head>
<body>
<h1>3rd party content with an SVG image background</h1>
<script>
onload = function(e) {
parent.postMessage({ type: "finish" }, "*");
};
</script>
</body>
</html>

View File

@ -3,6 +3,7 @@ support-files =
head.js
page.html
3rdParty.html
3rdPartySVG.html
3rdPartyUI.html
3rdPartyWO.html
3rdPartyOpen.html
@ -10,6 +11,7 @@ support-files =
empty.js
popup.html
[browser_backgroundImageAssertion.js]
[browser_blockingCookies.js]
support-files = server.sjs
[browser_blockingIndexedDb.js]

View File

@ -0,0 +1,56 @@
ChromeUtils.import("resource://gre/modules/Services.jsm");
add_task(async function() {
info("Starting subResources test");
await SpecialPowers.flushPrefEnv();
await SpecialPowers.pushPrefEnv({"set": [
["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();
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
await ContentTask.spawn(browser,
{ page: TEST_3RD_PARTY_PAGE_WITH_SVG,
},
async function(obj) {
await new content.Promise(resolve => {
let ifr = content.document.createElement("iframe");
content.addEventListener("message", function msg(event) {
if (event.data.type == "finish") {
content.removeEventListener("message", msg);
resolve();
return;
}
ok(false, "Unknown message");
});
content.document.body.appendChild(ifr);
ifr.src = obj.page;
});
});
ok(true, "No crash, hopefully!");
BrowserTestUtils.removeTab(tab);
UrlClassifierTestUtils.cleanupTestTrackers();
});
add_task(async function() {
info("Cleaning up.");
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
});
});

View File

@ -8,6 +8,7 @@ const TEST_POPUP_PAGE = TEST_DOMAIN + TEST_PATH + "popup.html";
const TEST_3RD_PARTY_PAGE = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdParty.html";
const TEST_3RD_PARTY_PAGE_WO = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdPartyWO.html";
const TEST_3RD_PARTY_PAGE_UI = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdPartyUI.html";
const TEST_3RD_PARTY_PAGE_WITH_SVG = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "3rdPartySVG.html";
var gFeatures = undefined;