Skip to content

Commit

Permalink
Reland "Make Clear-Site-Data: "cookies" respect third-party cookie bl…
Browse files Browse the repository at this point in the history
…ocking"

This is a reland of commit d27d50661e822cb64daec040041b5eabd2642969

Original change's description:
> Make Clear-Site-Data: "cookies" respect third-party cookie blocking
>
> This will prevent Clear-Site-Data from being abused for cross-site
> tracking [1] when partitioned cookies are enabled by default.
>
> [1]: privacycg/storage-partitioning#11
>
> Old behavior: Clear-Site-Data could clear unpartitioned cookies from any context.
>
> New behavior: Clear-Site-Data cannot clear unpartitioned cookies if it came from a response where 3P cookie blocking applies.
>
> In both cases, CSD will delete partitioned cookies in the current partition.
>
> Low-Coverage-Reason:Some files have trial changes that do not impact behavior.
>
> Bug: 1416655
> Change-Id: Ieed1e050f8f376b7d7704b4948c8f59adc21a17f
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4312585
> Reviewed-by: Nasko Oskov <[email protected]>
> Reviewed-by: Andrey Zaytsev <[email protected]>
> Reviewed-by: Maks Orlovich <[email protected]>
> Reviewed-by: Daniel Murphy <[email protected]>
> Commit-Queue: Dylan Cutler <[email protected]>
> Reviewed-by: Christian Dullweber <[email protected]>
> Reviewed-by: Oleh Lamzin <[email protected]>
> Cr-Commit-Position: refs/heads/main@{#1118080}

Bug: 1416655
Change-Id: I19deff390906e1d2fb7f990543d8ea5c438b4717
  • Loading branch information
DCtheTall authored and chromium-wpt-export-bot committed Mar 16, 2023
1 parent 071134c commit 9faaa95
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<meta charset="utf-8"/>
<meta name="timeout" content="long">
<title>Service Worker: Partitioned Cookies</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script src="/common/get-host-info.sub.js"></script>

<!--
This test exercises partitioned service workers' interaction with partitioned cookies.
Partitioned service workers should only be able to interact with partitioned cookies whose
partition key matches the worker's partition.
-->

<body>
</body>
<script>

promise_test(async t => {
const script = './resources/partitioned-cookies-sw.js'
const scope = './resources/partitioned-cookies-'
const absolute_scope = new URL(scope, window.location).href;

const reg = await service_worker_unregister_and_register(t, script, scope);
await wait_for_state(t, reg.installing, 'activated');
t.add_cleanup(() => reg.unregister());

// on_message will be reassigned below based on the expected reply from the service worker.
let on_message;
self.addEventListener('message', ev => on_message(ev));
navigator.serviceWorker.addEventListener('message', evt => {
self.postMessage(evt.data, '*');
});

let wait_promise;
let resolve_wait_promise;

const retrieved_registrations =
await navigator.serviceWorker.getRegistrations();
// It's possible that other tests have left behind other service workers.
// This steps filters those other SWs out.
const filtered_registrations =
retrieved_registrations.filter(reg => reg.scope == absolute_scope);

// First test that the worker script started correctly and message passing is enabed.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
let got;
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
filtered_registrations[0].active.postMessage({type: 'test_message'});
await wait_promise;
assert_true(got.ok, 'Message passing');

// Set a Partitioned cookie.
document.cookie = '__Host-partitioned=123; Secure; Path=/; SameSite=None; Partitioned;';
assert_true(document.cookie.includes('__Host-partitioned=123'));

// Test that the partitioned cookie is available to this worker.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
filtered_registrations[0].active.postMessage({type: 'echo_cookies'});
await wait_promise;
assert_true(got.ok, 'Get cookies');
assert_true(got.cookies.includes('__Host-partitioned'), 'Can access partitioned cookie');

const popup = window.open(
new URL(
`./resources/partitioned-cookies-3p-window.html?origin=${
encodeURIComponent(self.location.origin)}`,
get_host_info().HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname));
await fetch_tests_from_window(popup);
});

</script>
</html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<meta charset="utf-8"/>
<meta name="timeout" content="long">
<title>Service Worker: Partitioned Cookies 3P Iframe</title>
<script src="/resources/testharness.js"></script>
<script src="test-helpers.sub.js"></script>

<body>
</body>
<script>

promise_test(async t => {
const script = './partitioned-cookies-sw.js';
const scope = './partitioned-cookies-';
const absolute_scope = new URL(scope, window.location).href;

assert_false(document.cookie.includes('__Host-partitioned=123'), 'DOM cannot access partitioned cookie');

const reg = await service_worker_unregister_and_register(t, script, scope);
await wait_for_state(t, reg.installing, 'activated');

let retrieved_registrations =
await navigator.serviceWorker.getRegistrations();
let filtered_registrations =
retrieved_registrations.filter(reg => reg.scope == absolute_scope);

// on_message will be reassigned below based on the expected reply from the service worker.
let on_message;
self.addEventListener('message', ev => on_message(ev));
navigator.serviceWorker.addEventListener('message', evt => {
self.postMessage(evt.data, '*');
});

// First test that the worker script started correctly and message passing is enabed.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
let got;
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
filtered_registrations[0].active.postMessage({type: 'test_message'});
await wait_promise;
assert_true(got.ok, 'Message passing');

// Test that the partitioned cookie is not available to this worker.
wait_promise = new Promise(resolve => {
resolve_wait_promise = resolve;
});
on_message = ev => {
got = ev.data;
resolve_wait_promise();
};
filtered_registrations[0].active.postMessage({type: 'echo_cookies'});
await wait_promise;
assert_true(got.ok, 'Get cookies');
assert_false(
got.cookies.includes('__Host-partitioned'),
'Worker annot access partitioned cookie');
});

</script>
</html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<meta charset="utf-8"/>
<meta name="timeout" content="long">
<title>Service Worker: Partitioned Cookies 3P Window</title>
<script src="/resources/testharness.js"></script>

<body>
</body>
<script>

promise_test(async t => {
assert_true(
location.search.includes('origin='), 'First party origin passed');
const first_party_origin = decodeURIComponent(
location.search.split('origin=')[1]);
const iframe = document.createElement('iframe');
iframe.src = new URL(
'./partitioned-cookies-3p-frame.html',
first_party_origin + location.pathname).href;
document.body.appendChild(iframe);
fetch_tests_from_window(iframe.contentWindow);
});

</script>
</html>
30 changes: 30 additions & 0 deletions service-workers/service-worker/resources/partitioned-cookies-sw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
self.addEventListener('message', ev => ev.waitUntil(onMessage(ev)));

async function onMessage(event) {
if (!event.data)
return;
switch (event.data.type) {
case 'test_message':
return onTestMessage(event);
case 'echo_cookies':
return onEchoCookies(event);
default:
return;
}
}

// test_message just verifies that the message passing is working.
async function onTestMessage(event) {
event.source.postMessage({ok: true});
}

// echo_cookies returns the names of all of the cookies available to the worker.
async function onEchoCookies(event) {
try {
const cookie_objects = await self.cookieStore.getAll();
const cookies = cookie_objects.map(c => c.name);
event.source.postMessage({ok: true, cookies});
} catch (err) {
event.source.postMessage({ok: false});
}
}

0 comments on commit 9faaa95

Please sign in to comment.