Skip to content

Commit

Permalink
[html] Test COEP derivation in shared workers
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Pieters <[email protected]>
  • Loading branch information
jugglinmike and zcorpan authored Apr 6, 2021
1 parent a13852d commit 6eb96ee
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
body = b'''
'use strict';
onconnect = (event) => {
const port = event.ports[0];
port.onmessage = (event) => {
fetch(event.data, { mode: 'no-cors' })
.then(
() => port.postMessage('success'),
() => port.postMessage('failure')
);
};
port.postMessage('ready');
};'''

def main(request, response):
headers = [(b'Content-Type', b'text/javascript')]

for value in request.GET.get_list(b'value'):
headers.append((b'Cross-Origin-Embedder-Policy', value))

return (200, headers, body)
131 changes: 131 additions & 0 deletions html/cross-origin-embedder-policy/shared-workers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>COEP - policy derivation for Shared Workers</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<body>
<p>Verify the Cross-Origin Embedder Policy for Shared Workers by performing a
cross-domain "fetch" request for a resource that does not specify a COEP. Only
Shared Workers with the default COEP should be able to successfully perform
this operation.</p>
<script>
'use strict';
const testUrl = get_host_info().HTTPS_REMOTE_ORIGIN +
'/html/cross-origin-embedder-policy/resources/empty-coep.py';
const workerHttpUrl = get_host_info().HTTPS_ORIGIN +
'/html/cross-origin-embedder-policy/resources/shared-worker-fetch.js.py';
let workerBlobUrl;
let workerDataUrl;

promise_setup(() => {
return fetch(workerHttpUrl)
.then((response) => response.text())
.then((text) => {
workerDataUrl = 'data:text/javascript;base64,' + btoa(text);
workerBlobUrl = URL.createObjectURL(
new Blob([text], { 'Content-Type': 'text/javascript' })
);
});
});

/**
* Create a Shared Worker within an iframe
*
* @param {object} t - a testharness.js subtest instance (used to reset global
* state)
* @param {string} ownerCoep - the Cross-Origin Embedder Policy of the iframe
* @param {string} workerUrl - the URL from which the Shared Worker should be
* created
*/
function create(t, ownerCoep, workerUrl) {
const iframe = document.createElement('iframe');
iframe.src = 'resources/empty-coep.py' +
(ownerCoep ? '?value=' + ownerCoep : '');

return new Promise((resolve, reject) => {
document.body.appendChild(iframe);
t.add_cleanup(() => iframe.remove());
iframe.onload = () => resolve(iframe);
})
.then((iframe) => {
const sw = new iframe.contentWindow.SharedWorker(workerUrl);

return new Promise((resolve) => {
sw.port.addEventListener('message', () => resolve(sw), { once: true });
sw.port.start();
});
});
}

/**
* Instruct a Shared Worker to fetch from a specified URL and report on the
* success of the operation.
*
* @param {SharedWorker} worker
* @param {string} url - the URL that the worker should fetch
*/
function fetchFromWorker(worker, url) {
return new Promise((resolve) => {
worker.port.postMessage(url);
worker.port.addEventListener(
'message', (event) => resolve(event.data), { once: true }
);
});
};

promise_test((t) => {
return create(t, null, workerHttpUrl)
.then((worker) => fetchFromWorker(worker, testUrl))
.then((result) => assert_equals(result, 'success'));
}, 'default policy (derived from response)');

promise_test((t) => {
return create(t, null, workerHttpUrl + '?value=require-corp')
.then((worker) => fetchFromWorker(worker, testUrl))
.then((result) => assert_equals(result, 'failure'));
}, '"require-corp" (derived from response)');

promise_test((t) => {
return Promise.all([
create(t, null, workerBlobUrl),
create(t, null, workerBlobUrl),
create(t, null, workerBlobUrl)
])
.then((workers) => fetchFromWorker(workers[0], testUrl))
.then((result) => assert_equals(result, 'success'));
}, 'default policy (derived from owner set due to use of local scheme - blob URL)');

promise_test((t) => {
return Promise.all([
create(t, null, workerBlobUrl),
create(t, 'require-corp', workerBlobUrl),
create(t, null, workerBlobUrl)
])
.then((workers) => fetchFromWorker(workers[0], testUrl))
.then((result) => assert_equals(result, 'failure'));
}, '"require-corp" (derived from owner set due to use of local scheme - blob URL)');

promise_test((t) => {
return Promise.all([
create(t, null, workerDataUrl),
create(t, null, workerDataUrl),
create(t, null, workerDataUrl)
])
.then((workers) => fetchFromWorker(workers[0], testUrl))
.then((result) => assert_equals(result, 'success'));
}, 'default policy (derived from owner set due to use of local scheme - data URL)');

promise_test((t) => {
return Promise.all([
create(t, null, workerDataUrl),
create(t, 'require-corp', workerDataUrl),
create(t, null, workerDataUrl)
])
.then((workers) => fetchFromWorker(workers[0], testUrl))
.then((result) => assert_equals(result, 'failure'));
}, '"require-corp" (derived from owner set due to use of local scheme - data URL)');
</script>
</body>
</html>

0 comments on commit 6eb96ee

Please sign in to comment.