author | arthursonzogni <arthursonzogni@chromium.org> |
Wed, 10 Jun 2020 11:27:32 +0000 | |
changeset 535332 | 0e8d48cd6e889226979f661c97bdccf05b90d3d6 |
parent 535331 | ce1211465f3b52bd6103a241804045459a9158ad |
child 535333 | 08093a76270156ac164fac2ee6087cde2edd2745 |
push id | 37501 |
push user | nbeleuzu@mozilla.com |
push date | Sat, 13 Jun 2020 03:21:52 +0000 |
treeherder | mozilla-central@80b6f21783a3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | testonly |
bugs | 1643084, 23954, 922191, 2228884, 775020 |
milestone | 79.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/access-reporting/META.yml @@ -0,0 +1,6 @@ +suggested_reviewers: + - ArthurSonzogni + - ParisMeuleman + - camillelamy + - hemeryar + - mikewest
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/access-reporting/openee-accessed_openee-coop-ro.https.html @@ -0,0 +1,84 @@ +<title> + COOP reports are sent when the openee used COOP-RO+COEP and then its opener + tries to access it. +</title> +<meta name=timeout content=long> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/common/get-host-info.sub.js></script> +<script src="/common/utils.js"></script> +<script src="./resources/dispatcher.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy/access-reporting"; +const executor_path = directory + "/resources/executor.html?pipe="; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; +const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)'; + +let operation = [ +//[test name , operation ] , + ["Call blur" , w => w.blur() ] , + ["Call foo" , w => w.foo() ] , + ["Call location" , w => w.location() ] , + ["Call opener" , w => w.opener() ] , + ["Call postMessage" , w => w.postMessage() ] , + ["Call window" , w => w.window() ] , + ["Read blur" , w => w.blur ] , + ["Read foo" , w => w.foo ] , + ["Read location" , w => w.location ] , + ["Read opener" , w => w.opener ] , + ["Read postMessage" , w => w.postMessage ] , + ["Read window" , w => w.window ] , + ["Write blur" , w => w.blur = "test" ] , + ["Write foo" , w => w.foo = "test" ] , + ["Write location" , w => w.location = "test" ] , + ["Write opener" , w => w.opener = "test" ] , + ["Write postMessage" , w => w.postMessage = "test" ] , + ["Write window" , w => w.window = "test" ] , +]; + +operation.forEach(([test, op]) => { + promise_test(async t => { + const report_token = token(); + const executor_token = token(); + const callback_token = token(); + + const reportTo = reportToHeaders(report_token); + const openee_url = cross_origin + executor_path + + reportTo.header + reportTo.coopReportOnlySameOrigin + coep_header + + `&uuid=${executor_token}`; + const openee = window.open(openee_url); + t.add_cleanup(() => send(executor_token, "window.close()")) + + // 1. Make sure the new document to be loaded. + send(executor_token, ` + send("${callback_token}", "Ready"); + `); + let reply = await receive(callback_token); + assert_equals(reply, "Ready"); + + // 2. Skip the first report about the opener breakage. + let report_1 = await receive(report_token); + assert_not_equals(report_1, "timeout"); + report_1 = JSON.parse(report_1); + assert_equals(report_1.length, 1); + assert_equals(report_1[0].type, "coop"); + assert_equals(report_1[0].body["violation-type"], "navigation-to-document"); + assert_equals(report_1[0].body["disposition"], "reporting"); + + // 3. Try to access the openee. A report is sent, because of COOP-RO+COEP. + try {op(openee)} catch(e) {} + + // 4. A COOP access reports must be sent as a result of (3). + let report_2 = await receive(report_token); + assert_not_equals(report_1, "timeout"); + report_2 = JSON.parse(report_2); + assert_equals(report_2.length, 1); + assert_equals(report_2[0].type, "coop"); + assert_equals(report_2[0].body["violation-type"], "access"); + assert_equals(report_2[0].body["disposition"], "reporting"); + assert_equals(report_2[0].body["effective-policy"], "same-origin-plus-coep"); + }, `${test}`); +}); + +</script>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/access-reporting/openee-accessed_openee-coop.https.html @@ -0,0 +1,84 @@ +<title> + COOP reports are sent when the openee used COOP+COEP and then its opener + tries to access it. +</title> +<meta name=timeout content=long> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/common/get-host-info.sub.js></script> +<script src="/common/utils.js"></script> +<script src="./resources/dispatcher.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy/access-reporting"; +const executor_path = directory + "/resources/executor.html?pipe="; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; +const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)'; + +let operation = [ +//[test name , operation ] , + ["Call blur" , w => w.blur() ] , + ["Call foo" , w => w.foo() ] , + ["Call location" , w => w.location() ] , + ["Call opener" , w => w.opener() ] , + ["Call postMessage" , w => w.postMessage() ] , + ["Call window" , w => w.window() ] , + ["Read blur" , w => w.blur ] , + ["Read foo" , w => w.foo ] , + ["Read location" , w => w.location ] , + ["Read opener" , w => w.opener ] , + ["Read postMessage" , w => w.postMessage ] , + ["Read window" , w => w.window ] , + ["Write blur" , w => w.blur = "test" ] , + ["Write foo" , w => w.foo = "test" ] , + ["Write location" , w => w.location = "test" ] , + ["Write opener" , w => w.opener = "test" ] , + ["Write postMessage" , w => w.postMessage = "test" ] , + ["Write window" , w => w.window = "test" ] , +]; + +operation.forEach(([test, op]) => { + promise_test(async t => { + const report_token = token(); + const executor_token = token(); + const callback_token = token(); + + const reportTo = reportToHeaders(report_token); + const openee_url = cross_origin + executor_path + + reportTo.header + reportTo.coopSameOrigin + coep_header + + `&uuid=${executor_token}`; + const openee = window.open(openee_url); + t.add_cleanup(() => send(executor_token, "window.close()")) + + // 1. Make sure the new document to be loaded. + send(executor_token, ` + send("${callback_token}", "Ready"); + `); + let reply = await receive(callback_token); + assert_equals(reply, "Ready"); + + // 2. Skip the first report about the opener breakage. + let report_1 = await receive(report_token); + assert_not_equals(report_1, "timeout"); + report_1 = JSON.parse(report_1); + assert_equals(report_1.length, 1); + assert_equals(report_1[0].type, "coop"); + assert_equals(report_1[0].body["violation-type"], "navigation-to-document"); + assert_equals(report_1[0].body["disposition"], "enforce"); + + // 3. Try to access the openee. This shouldn't work because of COOP+COEP. + try {op(openee)} catch(e) {} + + // 4. A COOP access reports must be sent as a result of (3). + let report_2 = await receive(report_token); + assert_not_equals(report_2, "timeout"); + report_2 = JSON.parse(report_2); + assert_equals(report_2.length, 1); + assert_equals(report_2[0].type, "coop"); + assert_equals(report_2[0].body["violation-type"], "access"); + assert_equals(report_2[0].body["disposition"], "enforce"); + assert_equals(report_2[0].body["effective-policy"], "same-origin-plus-coep"); + }, `${test}`); +}); + +</script>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/access-reporting/opener-accessed_openee-coop-ro.https.html @@ -0,0 +1,83 @@ +<title> + COOP reports are sent when the openee used COOP-RO+COEP and then tries to + access its opener. +</title> +<meta name=timeout content=long> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/common/get-host-info.sub.js></script> +<script src="/common/utils.js"></script> +<script src="./resources/dispatcher.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy/access-reporting"; +const executor_path = directory + "/resources/executor.html?pipe="; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; +const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)'; + +let operation = [ +//[test name , operation ] , + ["Call blur" , "opener.blur()" ] , + ["Call foo" , "opener.foo()" ] , + ["Call location" , "opener.location()" ] , + ["Call opener" , "opener.opener()" ] , + ["Call postMessage" , "opener.postMessage()" ] , + ["Call window" , "opener.window()" ] , + ["Read blur" , "opener.blur" ] , + ["Read foo" , "opener.foo" ] , + ["Read location" , "opener.location" ] , + ["Read opener" , "opener.opener" ] , + ["Read postMessage" , "opener.postMessage" ] , + ["Read window" , "opener.window" ] , + ["Write blur" , "opener.blur = 'test'" ] , + ["Write foo" , "opener.foo = 'test'" ] , + ["Write location" , "opener.location = 'test'" ] , + ["Write opener" , "opener.opener = 'test'" ] , + ["Write postMessage" , "opener.postMessage = 'test'" ] , + ["Write window" , "opener.window = 'test'" ] , +]; + +operation.forEach(([test, op]) => { + promise_test(async t => { + const report_token = token(); + const executor_token = token(); + const callback_token = token(); + + const reportTo = reportToHeaders(report_token); + const openee_url = cross_origin + executor_path + + reportTo.header + reportTo.coopReportOnlySameOrigin + coep_header + + `&uuid=${executor_token}`; + const openee = window.open(openee_url); + t.add_cleanup(() => send(executor_token, "window.close()")) + + // 1. Skip the first report about the opener breakage. + let report_1 = await receive(report_token); + assert_not_equals(report_1, "timeout"); + report_1 = JSON.parse(report_1); + assert_equals(report_1.length, 1); + assert_equals(report_1[0].type, "coop"); + assert_equals(report_1[0].body["violation-type"], "navigation-to-document"); + assert_equals(report_1[0].body["disposition"], "reporting"); + + // 3. Try to access the opener. A report is sent, because of COOP-RO+COEP. + send(executor_token, ` + try {${op}} catch(e) {} + send("${callback_token}", "Done"); + `); + let reply = await receive(callback_token); + assert_equals(reply, "Done"); + + // 4. A COOP access reports must be sent as a result of (3). + let report_2 = await receive(report_token); + assert_not_equals(report_2, "timeout"); + report_2 = JSON.parse(report_2); + + assert_equals(report_2.length, 1); + assert_equals(report_2[0].type, "coop"); + assert_equals(report_2[0].body["violation-type"], "access"); + assert_equals(report_2[0].body["disposition"], "reporting"); + assert_equals(report_2[0].body["effective-policy"], "same-origin-plus-coep"); + }, `${test}`); +}); + +</script>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/access-reporting/opener-accessed_openee-coop.https.html @@ -0,0 +1,83 @@ +<title> + COOP reports are sent when the openee used COOP+COEP and then tries to + access its opener. +</title> +<meta name=timeout content=long> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/common/get-host-info.sub.js></script> +<script src="/common/utils.js"></script> +<script src="./resources/dispatcher.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy/access-reporting"; +const executor_path = directory + "/resources/executor.html?pipe="; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; +const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)'; + +let operation = [ +//[test name , operation ] , + ["Call blur" , "opener.blur()" ] , + ["Call foo" , "opener.foo()" ] , + ["Call location" , "opener.location()" ] , + ["Call opener" , "opener.opener()" ] , + ["Call postMessage" , "opener.postMessage()" ] , + ["Call window" , "opener.window()" ] , + ["Read blur" , "opener.blur" ] , + ["Read foo" , "opener.foo" ] , + ["Read location" , "opener.location" ] , + ["Read opener" , "opener.opener" ] , + ["Read postMessage" , "opener.postMessage" ] , + ["Read window" , "opener.window" ] , + ["Write blur" , "opener.blur = 'test'" ] , + ["Write foo" , "opener.foo = 'test'" ] , + ["Write location" , "opener.location = 'test'" ] , + ["Write opener" , "opener.opener = 'test'" ] , + ["Write postMessage" , "opener.postMessage = 'test'" ] , + ["Write window" , "opener.window = 'test'" ] , +]; + +operation.forEach(([test, op]) => { + promise_test(async t => { + const report_token = token(); + const executor_token = token(); + const callback_token = token(); + + const reportTo = reportToHeaders(report_token); + const openee_url = cross_origin + executor_path + + reportTo.header + reportTo.coopSameOrigin + coep_header + + `&uuid=${executor_token}`; + const openee = window.open(openee_url); + t.add_cleanup(() => send(executor_token, "window.close()")); + + // 1. Skip the first report about the opener breakage. + let report_1 = await receive(report_token); + assert_not_equals(report_1, "timeout"); + report_1 = JSON.parse(report_1); + assert_equals(report_1.length, 1); + assert_equals(report_1[0].type, "coop"); + assert_equals(report_1[0].body["violation-type"], "navigation-to-document"); + assert_equals(report_1[0].body["disposition"], "enforce"); + + // 3. Try to access the opener. A report is sent, because of COOP-RO+COEP. + send(executor_token, ` + try {${op}} catch(e) {} + send("${callback_token}", "Done"); + `); + let reply = await receive(callback_token); + assert_equals(reply, "Done"); + + // 4. A COOP access reports must be sent as a result of (3). + let report_2 = await receive(report_token); + assert_not_equals(report_2, "timeout"); + report_2 = JSON.parse(report_2); + + assert_equals(report_2.length, 1); + assert_equals(report_2[0].type, "coop"); + assert_equals(report_2[0].body["violation-type"], "access"); + assert_equals(report_2[0].body["disposition"], "enforce"); + assert_equals(report_2[0].body["effective-policy"], "same-origin-plus-coep"); + }, `${test}`); +}); + +</script>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/access-reporting/resources/dispatcher.js @@ -0,0 +1,55 @@ +// Define an universal message passing API. +// +// In particular, this works: +// - cross-origin and +// - cross-browsing-context-group. +// +// It can also be used to receive reports. + +const dispatcher_path = + '/html/cross-origin-opener-policy/access-reporting/resources/dispatcher.py'; +const dispatcher_url = new URL(dispatcher_path, location.href).href; + +const send = function(uuid, message) { + fetch(dispatcher_url + `?uuid=${uuid}`, { + method: 'POST', + body: message + }); +} + +const receive = async function(uuid) { + const timeout = 3000; + const retry_delay = 100; + for(let i = 0; i * retry_delay < timeout; ++i) { + let response = await fetch(dispatcher_url + `?uuid=${uuid}`); + let data = await response.text(); + if (data != 'not ready') + return data; + await new Promise(r => step_timeout(r, retry_delay)); + } + return "timeout"; +} + +// Build a set of headers to tests the reporting API. This defines a set of +// matching 'Report-To', 'Cross-Origin-Opener-Policy' and +// 'Cross-Origin-Opener-Policy-Report-Only' headers. +const reportToHeaders = function(uuid) { + const report_endpoint_url = dispatcher_path + `?uuid=${uuid}`; + let reportToJSON = { + 'group': `${uuid}`, + 'max_age': 3600, + 'endpoints': [ + {'url': report_endpoint_url.toString()}, + ] + }; + reportToJSON = JSON.stringify(reportToJSON) + .replace(/,/g, '\\,') + .replace(/\(/g, '\\\(') + .replace(/\)/g, '\\\)='); + + return { + header: `|header(report-to,${reportToJSON})`, + coopSameOrigin: `|header(Cross-Origin-Opener-Policy, same-origin%3Breport-to="${uuid}")`, + coopReportOnlySameOrigin: `|header(Cross-Origin-Opener-Policy-Report-Only, same-origin%3Breport-to="${uuid}")`, + }; +};
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/access-reporting/resources/dispatcher.py @@ -0,0 +1,22 @@ +# A server used to store and retrieve arbitrary data. +# This is used by: ./dispatcher.js +import json + +def main(request, response): + response.headers.set('Access-Control-Allow-Origin', '*') + response.headers.set('Access-Control-Allow-Methods', 'OPTIONS, GET, POST') + response.headers.set('Access-Control-Allow-Headers', 'Content-Type') + response.headers.set('Cache-Control', 'no-cache, no-store, must-revalidate'); + if request.method == 'OPTIONS': # CORS preflight + return '' + + uuid = request.GET['uuid'] + + if request.method == 'POST': + return request.server.stash.put(uuid, request.body) + else: + body = request.server.stash.take(uuid) + if body is None: + return 'not ready' + else: + return body
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/access-reporting/resources/executor.html @@ -0,0 +1,12 @@ +<script src=/resources/testharness.js></script> +<script src="./dispatcher.js"></script> +<script> + const params = new URLSearchParams(window.location.search); + const uuid = params.get('uuid'); + + let executeOrders = async function() { + while(true) + eval(await receive(uuid)); + }; + executeOrders(); +</script>