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:
Andrea Marchesini 2019-06-05 07:48:59 +00:00
Родитель f6f463d037
Коммит 7b16930b86
9 изменённых файлов: 328 добавлений и 1 удалений

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

@ -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();
}
});
},
};