зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1556046 - Add tests to ensure separate tabs with partitioning get partitioned storage, r=Ehsan
Differential Revision: https://phabricator.services.mozilla.com/D33519 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
f6f463d037
Коммит
7b16930b86
|
@ -0,0 +1,21 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>3rd party content!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Here the 3rd party content!</h1>
|
||||
<script>
|
||||
|
||||
onmessage = async function(e) {
|
||||
let cb = e.data.cb;
|
||||
let runnableStr = `(() => {return (${cb});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
|
||||
let result = await runnable.call(this, this, e.data.value);
|
||||
parent.postMessage(result, "*");
|
||||
};
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -29,6 +29,7 @@ support-files =
|
|||
storageAccessAPIHelpers.js
|
||||
3rdPartyStorage.html
|
||||
3rdPartyStorageWO.html
|
||||
3rdPartyPartitioned.html
|
||||
!/browser/modules/test/browser/head.js
|
||||
!/browser/base/content/test/general/head.js
|
||||
|
||||
|
@ -105,4 +106,4 @@ support-files = cookies.sjs
|
|||
[browser_partitionedServiceWorkers.js]
|
||||
support-files = matchAll.js
|
||||
[browser_partitionedSharedWorkers.js]
|
||||
support-files = sharedWorker.js
|
||||
support-files = sharedWorker.js partitionedSharedWorker.js
|
||||
|
|
|
@ -47,3 +47,49 @@ PartitionedStorageHelper.runTest("DOM Cookies",
|
|||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||
});
|
||||
});
|
||||
|
||||
PartitionedStorageHelper.runPartitioningTest(
|
||||
"Partitioned tabs - DOM Cookies",
|
||||
|
||||
// getDataCallback
|
||||
async win => {
|
||||
return win.document.cookie;
|
||||
},
|
||||
|
||||
// addDataCallback
|
||||
async (win, value) => {
|
||||
win.document.cookie = value;
|
||||
return true;
|
||||
},
|
||||
|
||||
// cleanup
|
||||
async _ => {
|
||||
await new Promise(resolve => {
|
||||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
PartitionedStorageHelper.runPartitioningTest(
|
||||
"Partitioned tabs - Network Cookies",
|
||||
|
||||
// getDataCallback
|
||||
async win => {
|
||||
return win.fetch("cookies.sjs").then(r => r.text()).then(text => {
|
||||
return text.substring("cookie:foopy=".length);
|
||||
});
|
||||
},
|
||||
|
||||
// addDataCallback
|
||||
async (win, value) => {
|
||||
await win.fetch("cookies.sjs?" + value).then(r => r.text());
|
||||
return true;
|
||||
},
|
||||
|
||||
// cleanup
|
||||
async _ => {
|
||||
await new Promise(resolve => {
|
||||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -44,3 +44,46 @@ PartitionedStorageHelper.runTest("IndexedDB",
|
|||
});
|
||||
});
|
||||
|
||||
PartitionedStorageHelper.runPartitioningTest(
|
||||
"Partitioned tabs - IndexedDB",
|
||||
|
||||
// getDataCallback
|
||||
async win => {
|
||||
return new Promise(resolve => {
|
||||
let a = win.indexedDB.open("test", 1);
|
||||
|
||||
a.onupgradeneeded = e => {
|
||||
let db = e.target.result;
|
||||
db.createObjectStore("foobar", {keyPath: "id"});
|
||||
};
|
||||
|
||||
a.onsuccess = e => {
|
||||
let db = e.target.result;
|
||||
db.transaction("foobar").objectStore("foobar").get(1).onsuccess = ee => {
|
||||
resolve(ee.target.result === undefined ? "" : ee.target.result.value);
|
||||
};
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
// addDataCallback
|
||||
async (win, value) => {
|
||||
return new Promise(resolve => {
|
||||
let a = win.indexedDB.open("test", 1);
|
||||
|
||||
a.onsuccess = e => {
|
||||
let db = e.target.result;
|
||||
db.transaction("foobar", "readwrite").objectStore("foobar").add({ id: 1, value }).onsuccess = _ => {
|
||||
resolve(true);
|
||||
};
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
// cleanup
|
||||
async _ => {
|
||||
await new Promise(resolve => {
|
||||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* import-globals-from antitracking_head.js */
|
||||
/* import-globals-from partitionedstorage_head.js */
|
||||
|
||||
AntiTracking.runTest("localStorage and Storage Access API",
|
||||
async _ => {
|
||||
|
@ -76,3 +77,25 @@ AntiTracking.runTest("localStorage and Storage Access API",
|
|||
},
|
||||
[["privacy.restrict3rdpartystorage.partitionedHosts", "tracking.example.org,tracking.example.com"]],
|
||||
false, false);
|
||||
|
||||
PartitionedStorageHelper.runPartitioningTest(
|
||||
"Partitioned tabs - localStorage",
|
||||
|
||||
// getDataCallback
|
||||
async win => {
|
||||
return ("foo" in win.localStorage) ? win.localStorage.foo : "";
|
||||
},
|
||||
|
||||
// addDataCallback
|
||||
async (win, value) => {
|
||||
win.localStorage.foo = value;
|
||||
return true;
|
||||
},
|
||||
|
||||
// cleanup
|
||||
async _ => {
|
||||
await new Promise(resolve => {
|
||||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -40,3 +40,27 @@ PartitionedStorageHelper.runTest("SharedWorkers",
|
|||
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||
});
|
||||
});
|
||||
|
||||
PartitionedStorageHelper.runPartitioningTest(
|
||||
"Partitioned tabs - SharedWorker",
|
||||
|
||||
// getDataCallback
|
||||
async win => {
|
||||
win.sh = new win.SharedWorker("partitionedSharedWorker.js");
|
||||
return new Promise(resolve => {
|
||||
win.sh.port.onmessage = e => {
|
||||
resolve(e.data);
|
||||
};
|
||||
win.sh.port.postMessage({what: "get"});
|
||||
});
|
||||
},
|
||||
|
||||
// addDataCallback
|
||||
async (win, value) => {
|
||||
win.sh.port.postMessage({what: "put", value});
|
||||
return true;
|
||||
},
|
||||
|
||||
// cleanup
|
||||
async _ => {}
|
||||
);
|
||||
|
|
|
@ -35,6 +35,7 @@ const TEST_4TH_PARTY_PAGE = TEST_4TH_PARTY_DOMAIN + TEST_PATH + "3rdParty.html";
|
|||
const TEST_ANOTHER_3RD_PARTY_PAGE = TEST_ANOTHER_3RD_PARTY_DOMAIN + TEST_PATH + "3rdParty.html";
|
||||
const TEST_3RD_PARTY_STORAGE_PAGE = TEST_3RD_PARTY_DOMAIN_HTTP + TEST_PATH + "3rdPartyStorage.html";
|
||||
const TEST_4TH_PARTY_STORAGE_PAGE = TEST_4TH_PARTY_DOMAIN + TEST_PATH + "3rdPartyStorage.html";
|
||||
const TEST_4TH_PARTY_PARTITIONED_PAGE = TEST_4TH_PARTY_DOMAIN + TEST_PATH + "3rdPartyPartitioned.html";
|
||||
|
||||
const BEHAVIOR_ACCEPT = Ci.nsICookieService.BEHAVIOR_ACCEPT;
|
||||
const BEHAVIOR_REJECT = Ci.nsICookieService.BEHAVIOR_REJECT;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
let value = "";
|
||||
self.onconnect = e => {
|
||||
e.ports[0].onmessage = event => {
|
||||
if (event.data.what === "get") {
|
||||
e.ports[0].postMessage(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.data.what === "put") {
|
||||
value += event.data.value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Error.
|
||||
e.ports[0].postMessage(-1);
|
||||
};
|
||||
};
|
||||
|
|
@ -22,4 +22,154 @@ this.PartitionedStorageHelper = {
|
|||
DynamicFPIHelper.runTest(name, callback, cleanupFunction, extraPrefs);
|
||||
StoragePrincipalHelper.runTest(name, callback, cleanupFunction, extraPrefs);
|
||||
},
|
||||
|
||||
runPartitioningTest(name, getDataCallback, addDataCallback, cleanupFunction) {
|
||||
add_task(async _ => {
|
||||
info("Starting test `" + name + "' to check that 2 tabs are correctly partititioned");
|
||||
|
||||
await SpecialPowers.flushPrefEnv();
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.storage_access.enabled", true],
|
||||
["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN],
|
||||
["privacy.trackingprotection.enabled", false],
|
||||
["privacy.trackingprotection.pbmode.enabled", false],
|
||||
["privacy.trackingprotection.annotate_channels", true],
|
||||
["privacy.storagePrincipal.enabledForTrackers", false],
|
||||
["privacy.restrict3rdpartystorage.userInteractionRequiredForHosts", "not-tracking.example.com"],
|
||||
]});
|
||||
|
||||
info("Creating the first tab");
|
||||
let tab1 = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
|
||||
gBrowser.selectedTab = tab1;
|
||||
|
||||
let browser1 = gBrowser.getBrowserForTab(tab1);
|
||||
await BrowserTestUtils.browserLoaded(browser1);
|
||||
|
||||
info("Creating the second tab");
|
||||
let tab2 = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE_6);
|
||||
gBrowser.selectedTab = tab2;
|
||||
|
||||
let browser2 = gBrowser.getBrowserForTab(tab2);
|
||||
await BrowserTestUtils.browserLoaded(browser2);
|
||||
|
||||
info("Creating the third tab");
|
||||
let tab3 = BrowserTestUtils.addTab(gBrowser, TEST_4TH_PARTY_PARTITIONED_PAGE);
|
||||
gBrowser.selectedTab = tab3;
|
||||
|
||||
let browser3 = gBrowser.getBrowserForTab(tab3);
|
||||
await BrowserTestUtils.browserLoaded(browser3);
|
||||
|
||||
async function getDataFromThirdParty(browser, result) {
|
||||
await ContentTask.spawn(browser, {
|
||||
page: TEST_4TH_PARTY_PARTITIONED_PAGE,
|
||||
getDataCallback: getDataCallback.toString(),
|
||||
result,
|
||||
},
|
||||
async obj => {
|
||||
await new content.Promise(resolve => {
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.onload = __ => {
|
||||
info("Sending code to the 3rd party content");
|
||||
ifr.contentWindow.postMessage({ cb: obj.getDataCallback }, "*");
|
||||
};
|
||||
|
||||
content.addEventListener("message", function msg(event) {
|
||||
is(event.data, obj.result, "Partitioned cookie jar has value: " + obj.result);
|
||||
resolve();
|
||||
}, {once: true});
|
||||
|
||||
content.document.body.appendChild(ifr);
|
||||
ifr.src = obj.page;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function getDataFromFirstParty(browser, result) {
|
||||
await ContentTask.spawn(browser, {
|
||||
getDataCallback: getDataCallback.toString(),
|
||||
result,
|
||||
},
|
||||
async obj => {
|
||||
let runnableStr = `(() => {return (${obj.getDataCallback});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
|
||||
let result = await runnable.call(content, content);
|
||||
is(result, obj.result, "Partitioned cookie jar is empty: " + obj.result);
|
||||
});
|
||||
}
|
||||
|
||||
info("Checking 3rd party has an empty cookie jar in first tab");
|
||||
await getDataFromThirdParty(browser1, "");
|
||||
|
||||
info("Checking 3rd party has an empty cookie jar in second tab");
|
||||
await getDataFromThirdParty(browser2, "");
|
||||
|
||||
info("Checking first party has an empty cookie jar in third tab");
|
||||
await getDataFromFirstParty(browser3, "");
|
||||
|
||||
async function createDataInThirdParty(browser, value) {
|
||||
await ContentTask.spawn(browser, {
|
||||
page: TEST_4TH_PARTY_PARTITIONED_PAGE,
|
||||
addDataCallback: addDataCallback.toString(),
|
||||
value,
|
||||
},
|
||||
async obj => {
|
||||
await new content.Promise(resolve => {
|
||||
let ifr = content.document.getElementsByTagName("iframe")[0];
|
||||
content.addEventListener("message", function msg(event) {
|
||||
ok(event.data, "Data created");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
|
||||
ifr.contentWindow.postMessage({
|
||||
cb: obj.addDataCallback, value: obj.value }, "*");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function createDataInFirstParty(browser, value) {
|
||||
await ContentTask.spawn(browser, {
|
||||
addDataCallback: addDataCallback.toString(),
|
||||
value,
|
||||
},
|
||||
async obj => {
|
||||
let runnableStr = `(() => {return (${obj.addDataCallback});})();`;
|
||||
let runnable = eval(runnableStr); // eslint-disable-line no-eval
|
||||
|
||||
let result = await runnable.call(content, content, obj.value);
|
||||
ok(result, "Data created");
|
||||
});
|
||||
}
|
||||
|
||||
info("Creating data in the first tab");
|
||||
await createDataInThirdParty(browser1, "A");
|
||||
|
||||
info("Creating data in the second tab");
|
||||
await createDataInThirdParty(browser2, "B");
|
||||
|
||||
info("Creating data in the third tab");
|
||||
await createDataInFirstParty(browser3, "C");
|
||||
|
||||
info("First tab should still have just 'A'");
|
||||
await getDataFromThirdParty(browser1, "A");
|
||||
|
||||
info("Second tab should still have just 'B'");
|
||||
await getDataFromThirdParty(browser2, "B");
|
||||
|
||||
info("Third tab should still have just 'C'");
|
||||
await getDataFromFirstParty(browser3, "C");
|
||||
|
||||
info("Removing the tabs");
|
||||
BrowserTestUtils.removeTab(tab1);
|
||||
BrowserTestUtils.removeTab(tab2);
|
||||
BrowserTestUtils.removeTab(tab3);
|
||||
});
|
||||
|
||||
add_task(async _ => {
|
||||
info("Cleaning up.");
|
||||
if (cleanupFunction) {
|
||||
await cleanupFunction();
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче