Skip to content

Commit

Permalink
[shared storage] Support cross-origin worklet
Browse files Browse the repository at this point in the history
For the sharedStorage.createWorklet() API, relax the same-origin
restriction to additionally allow cross-origin script, in which case
a cross-origin worklet will be created.

How:
- Rely on CORS for the worklet to be created/used by the embedder.
- In general, we want to mimic the subframe's process allocation
behavior (i.e. it should end up using a process as if an iframe is
created with the script URL). It leverages the process allocation
and management logic from service workers and re-use SiteInstanceImpl::CreateForServiceWorker(). To keep this
CL focused, the refactoring will occur in a separate CL, as it
will involve refactoring other downstream components like
'UnmatchedServiceWorkerProcessTracker'.

Explainer: WICG/shared-storage#130
Spec: WICG/shared-storage#131
Design doc:
https://docs.google.com/document/d/1QTaaroCMeFVZVghI6JkUcDvmDQEacjvpyTfk6mpvQhA/edit?usp=sharing

Bug: 325302836
Change-Id: I11c1fc87bc76f4400c54d9fa809349d1d1781247
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5296843
Reviewed-by: Alex Moshchuk <[email protected]>
Commit-Queue: Yao Xiao <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1265583}
  • Loading branch information
yaoxiachromium authored and chromium-wpt-export-bot committed Feb 27, 2024
1 parent 07c9709 commit 0fc88db
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/shared-storage/resources/util.js"></script>
<script src="/fenced-frame/resources/utils.js"></script>

<body>
<script>
'use strict';

promise_test(async () => {
const ancestor_key = token();
const crossOrigin = 'https://{{domains[www]}}:{{ports[https][0]}}';
const set_cookie_url = crossOrigin + `/cookies/resources/set-cookie.py` +
`?name=key0` +
`&path=/shared-storage/`;
const helper_url = crossOrigin +
`/shared-storage/resources/credentials-test-helper.py` +
`?access_control_allow_origin_header=${window.origin}` +
`&access_control_allow_credentials_header=true` +
`&token=${ancestor_key}`;

await fetch(set_cookie_url, { mode: 'no-cors', credentials: 'include' });

const worklet = await sharedStorage.createWorklet(
helper_url + `&action=store-cookie`,
{ credentials: "include" });

const request_cookie_fetch_response =
await fetch(helper_url + `&action=get-cookie`);

const request_cookie_text = await request_cookie_fetch_response.text();

assert_equals(request_cookie_text, "key0=1");
}, 'createWorklet() with cross-origin module script and credentials "include"');

</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/shared-storage/resources/util.js"></script>
<script src="/fenced-frame/resources/utils.js"></script>

<body>
<script>
'use strict';

promise_test(async () => {
const ancestor_key = token();
const crossOrigin = 'https://{{domains[www]}}:{{ports[https][0]}}';
const set_cookie_url = crossOrigin + `/cookies/resources/set-cookie.py` +
`?name=key0` +
`&path=/shared-storage/`;
const helper_url = crossOrigin +
`/shared-storage/resources/credentials-test-helper.py` +
`?access_control_allow_origin_header=${window.origin}` +
`&token=${ancestor_key}`;

await fetch(set_cookie_url, { mode: 'no-cors', credentials: 'include' });

const worklet = await sharedStorage.createWorklet(
helper_url + `&action=store-cookie`,
{ credentials: "omit" });

const request_cookie_fetch_response =
await fetch(helper_url + `&action=get-cookie`);

const request_cookie_text = await request_cookie_fetch_response.text();

assert_equals(request_cookie_text, "NO_COOKIE_HEADER");
}, 'createWorklet() with cross-origin module script and credentials "omit"');

</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/shared-storage/resources/util.js"></script>
<script src="/fenced-frame/resources/utils.js"></script>

<body>
<script>
'use strict';

promise_test(async () => {
const ancestor_key = token();
const crossOrigin = 'https://{{domains[www]}}:{{ports[https][0]}}';
const set_cookie_url = crossOrigin + `/cookies/resources/set-cookie.py` +
`?name=key0` +
`&path=/shared-storage/`;
const helper_url = crossOrigin +
`/shared-storage/resources/credentials-test-helper.py` +
`?access_control_allow_origin_header=${window.origin}` +
`&token=${ancestor_key}`;

await fetch(set_cookie_url, { mode: 'no-cors', credentials: 'include' });

const worklet = await sharedStorage.createWorklet(
helper_url + `&action=store-cookie`,
{ credentials: "same-origin" });

const request_cookie_fetch_response =
await fetch(helper_url + `&action=get-cookie`);

const request_cookie_text = await request_cookie_fetch_response.text();

assert_equals(request_cookie_text, "NO_COOKIE_HEADER");
}, 'createWorklet() with cross-origin module script and credentials "same-origin"');

</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/shared-storage/resources/util.js"></script>
<script src="/fenced-frame/resources/utils.js"></script>

<body>
<script>
'use strict';

promise_test(async t => {
const ancestor_key = token();
const crossOrigin = 'https://{{domains[www]}}:{{ports[https][0]}}';
const helper_url = crossOrigin +
`/shared-storage/resources/credentials-test-helper.py` +
`?access_control_allow_origin_header=${window.origin}` +
`&token=${ancestor_key}`;

return promise_rejects_dom(t, "OperationError",
sharedStorage.createWorklet(
helper_url + `&action=store-cookie`,
{ credentials: "include" }));
}, 'createWorklet() with cross-origin module script and credentials ' +
'"include", and without the Access-Control-Allow-Credentials response ' +
'header');

</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/shared-storage/resources/util.js"></script>
<script src="/fenced-frame/resources/utils.js"></script>

<body>
<script>
'use strict';

promise_test(async t => {
const ancestor_key = token();
const crossOrigin = 'https://{{domains[www]}}:{{ports[https][0]}}';
const helper_url = crossOrigin +
`/shared-storage/resources/credentials-test-helper.py` +
`&access_control_allow_credentials_header=true` +
`&token=${ancestor_key}`;

return promise_rejects_dom(t, "OperationError",
sharedStorage.createWorklet(
helper_url + `&action=store-cookie`,
{ credentials: "include" }));
}, 'createWorklet() with cross-origin module script and credentials ' +
'"include", and without the Access-Control-Allow-Origin response header');

</script>
</body>
6 changes: 6 additions & 0 deletions shared-storage/resources/credentials-test-helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ def main(request, response):
response.status = 200
response.headers.append(b"Content-Type", b"text/javascript")

if b"access_control_allow_credentials_header" in request.GET:
response.headers.append(b"Access-Control-Allow-Credentials", request.GET[b"access_control_allow_credentials_header"])

if b"access_control_allow_origin_header" in request.GET:
response.headers.append(b"Access-Control-Allow-Origin", request.GET[b"access_control_allow_origin_header"])

if action == b"store-cookie":
cookie = request.headers.get(b"Cookie", b"NO_COOKIE_HEADER")
request.server.stash.put(token, cookie)
Expand Down

0 comments on commit 0fc88db

Please sign in to comment.