diff options
Diffstat (limited to 'testing/web-platform/tests/html/cross-origin-opener-policy/reporting')
68 files changed, 4074 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/META.yml b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/META.yml new file mode 100644 index 0000000000..0db28208a6 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/META.yml @@ -0,0 +1,6 @@ +suggested_reviewers: + - ArthurSonzogni + - ParisMeuleman + - camillelamy + - hemeryar + - mikewest diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro.https.html new file mode 100644 index 0000000000..a7e83cc0d9 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro.https.html @@ -0,0 +1,82 @@ +<title> + COOP reports are to the opener when the opener used COOP-RO+COEP and then it + tries to access a same-origin openee. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const redirect_path = directory + "/resources/redirect.py?"; +const same_origin = get_host_info().HTTPS_ORIGIN; + +let runTest = (openee_redirect, name) => promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP and a reporter. + const opener_report_token= token(); + const opener_token = token(); + const opener_reportTo = reportToHeaders(opener_report_token); + const opener_url = same_origin + executor_path + opener_reportTo.header + + opener_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window. This is same origin with the "opener". + const openee_report_token = token(); + const openee_token = token(); + const openee_url = same_origin + executor_path + `&uuid=${openee_token}`; + const openee_redirect_url = same_origin + redirect_path + openee_url + const openee_requested_url = openee_redirect ? openee_redirect_url + : openee_url; + + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close()")); + + // 2. The opener opens it openee. + send(opener_token, ` + openee = window.open("${openee_requested_url}"); + send("${this_window_token}", "ACK 1"); + `); + assert_equals("ACK 1", await receive(this_window_token)); + t.add_cleanup(() => send(openee_token, "window.close()")); + + // 3. Ensure the openee's document to be loaded. + send(openee_token, ` + send("${this_window_token}", "ACK 2"); + `); + assert_equals("ACK 2", await receive(this_window_token)); + + // 4. The opener tries to access its openee. + send(opener_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(openee);") + ); + // 5. Check a report sent to the opener. + let report = + await receiveReport(opener_report_token, "access-from-coop-page-to-openee") + assert_equals(report.type, "coop"); + assert_equals(report.url, opener_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_found(report); + assert_equals(report.body.openerURL, undefined); + assert_equals(report.body.openeeURL, openee_url); + assert_equals(report.body.otherDocumentURL, undefined); + assert_equals(report.body.referrer, undefined); + assert_equals(report.body.initialPopupURL, openee_requested_url); +}, name); + +runTest(false, "access-from-coop-page-to-openee, same-origin"); +runTest(true , "access-from-coop-page-to-openee, same-origin + redirect"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro_cross-origin.https.html new file mode 100644 index 0000000000..fe72a2299f --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-openee_coop-ro_cross-origin.https.html @@ -0,0 +1,85 @@ +<title> + COOP reports are to the opener when the opener used COOP-RO+COEP and then it + tries to access a cross-origin openee. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const redirect_path = directory + "/resources/redirect.py?"; +const same_origin = get_host_info().HTTPS_ORIGIN; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; + +let runTest = (openee_redirect, name) => promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP and a reporter. + const opener_report_token= token(); + const opener_token = token(); + const opener_reportTo = reportToHeaders(opener_report_token); + const opener_url = same_origin + executor_path + opener_reportTo.header + + opener_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window. This is cross origin with the "opener". + const openee_report_token= token(); + const openee_token = token(); + const openee_url = cross_origin + executor_path + `&uuid=${openee_token}`; + const openee_redirect_url = same_origin + redirect_path + openee_url + const openee_requested_url = openee_redirect ? openee_redirect_url + : openee_url; + + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close()")); + + // 2. The opener opens it openee. + send(opener_token, ` + openee = window.open("${openee_requested_url}"); + send("${this_window_token}", "ACK 1"); + `); + assert_equals("ACK 1", await receive(this_window_token)); + t.add_cleanup(() => send(openee_token, "window.close()")); + + // 3. Ensure the openee's document to be loaded. + send(openee_token, ` + send("${this_window_token}", "ACK 2"); + `); + assert_equals("ACK 2", await receive(this_window_token)); + + // 4. The opener tries to access its openee. + send(opener_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(openee);") + ); + + + // 5. Check a report sent to the opener. + let report = + await receiveReport(opener_report_token, "access-from-coop-page-to-openee") + assert_equals(report.type, "coop"); + assert_equals(report.url, opener_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_found(report); + assert_equals(report.body.openerURL, undefined); + assert_equals(report.body.openeeURL, ""); + assert_equals(report.body.otherDocumentURL, undefined); + assert_equals(report.body.referrer, undefined); + assert_equals(report.body.initialPopupURL, openee_requested_url); +}, name); + +runTest(false, "access-from-coop-page-to-openee, cross-origin"); +runTest(true , "access-from-coop-page-to-openee, cross-origin + redirect"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro.https.html new file mode 100644 index 0000000000..005339a06e --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro.https.html @@ -0,0 +1,63 @@ +<title> + COOP reports are sent when the openee used COOP-RO+COEP and then tries to + access its same-origin 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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const redirect_path = directory + "/resources/redirect.py?"; +const same_origin = get_host_info().HTTPS_ORIGIN; + +let runTest = (openee_redirect, name) => promise_test(async t => { + const report_token = token(); + const openee_token = token(); + + const opener_url = location.href; + + const reportTo = reportToHeaders(report_token); + const openee_url = same_origin + executor_path + + reportTo.header + reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + const openee_redirect_url = same_origin + redirect_path + openee_url + const openee_requested_url = openee_redirect ? openee_redirect_url + : openee_url; + + const openee = window.open(openee_requested_url); + t.add_cleanup(() => send(openee_token, "window.close()")) + + // 1. Try to access the opener. A report is sent, because of COOP-RO+COEP. + + send(openee_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(opener);") + ); + + // 2. Check a report is sent to the openee. + let report = + await receiveReport(report_token, "access-from-coop-page-to-opener") + assert_equals(report.type, "coop"); + assert_equals(report.url, openee_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_found(report); + assert_equals(report.body.openerURL, opener_url); + assert_equals(report.body.openeeURL, undefined); + assert_equals(report.body.otherDocumentURL, undefined); + assert_equals(report.body.referrer, opener_url); + assert_equals(report.body.initialPopupURL, undefined); +}, name); + +runTest(false, "access-from-coop-page-to-opener, same-origin"); +runTest(true , "access-from-coop-page-to-opener, same-origin + redirect"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro_cross-origin.https.html new file mode 100644 index 0000000000..eedfaa557f --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro_cross-origin.https.html @@ -0,0 +1,63 @@ +<title> + COOP reports are sent when the openee used COOP-RO+COEP and then tries to + access its cross-origin 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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const redirect_path = directory + "/resources/redirect.py?"; +const same_origin = get_host_info().HTTPS_ORIGIN; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; + +let runTest = (openee_redirect, name) => promise_test(async t => { + const report_token = token(); + const openee_token = token(); + + const opener_origin = location.origin + '/'; + + const reportTo = reportToHeaders(report_token); + const openee_url = cross_origin + executor_path + + reportTo.header + reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + const openee_redirect_url = same_origin + redirect_path + openee_url + const openee_requested_url = openee_redirect ? openee_redirect_url + : openee_url; + + const openee = window.open(openee_requested_url); + t.add_cleanup(() => send(openee_token, "window.close()")) + + // 1. Try to access the opener. A report is sent, because of COOP-RO+COEP. + send(openee_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(opener);") + ); + + // 2. Check a report is sent to the openee. + let report = + await receiveReport(report_token, "access-from-coop-page-to-opener") + assert_equals(report.type, "coop"); + assert_equals(report.url, openee_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_found(report); + assert_equals(report.body.openerURL, ""); + assert_equals(report.body.openeeURL, undefined); + assert_equals(report.body.otherDocumentURL, undefined); + assert_equals(report.body.referrer, opener_origin); + assert_equals(report.body.initialPopupURL, undefined); +}, name); + +runTest(false, "access-from-coop-page-to-opener, cross-origin"); +runTest(true , "access-from-coop-page-to-opener, cross-origin + redirect"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro.https.html new file mode 100644 index 0000000000..90df0e4e99 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro.https.html @@ -0,0 +1,92 @@ +<title> + One window accesses a second one. They are aren't related by an opener/openee + relationship. The first window has set + Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a + "access-from-coop-page-to-other" report. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const same_origin = get_host_info().HTTPS_ORIGIN; + +let escapeComma = url => url.replace(/,/g, '\\,'); + +promise_test(async t => { + const report_token= token(); + const report_to = reportToHeaders(report_token); + + // The test window. + const this_window_token = token(); + + // The "opener" window. With COOP:same-origin + reporter. + const opener_token = token(); + const opener_url = same_origin + executor_path + report_to.header + + report_to.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window. With COOP:same-origin + reporter. + const openee_token = token(); + const openee_url = same_origin + executor_path + report_to.header + + report_to.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + + // The "other" window. + const other_token = token(); + const other_url = same_origin + executor_path + report_to.header + + `&uuid=${other_token}`; + + t.add_cleanup(() => { + send(opener_token, "window.close()") + send(openee_token, "window.close()") + send(other_token, "window.close()") + }) + + // 1. Create the "opener" window. + let opener_window_proxy = window.open(opener_url); + + // 2. Create the "openee" window. + send(opener_token, ` + window.openee = window.open('${escapeComma(openee_url)}'); + `); + + // 3. Create the "other" window. + send(openee_token, ` + window.other = window.open('${escapeComma(other_url)}'); + `); + + // 4. Wait for "other" to load its document. + send(other_token, `send('${this_window_token}', "Loaded");`); + assert_equals(await receive(this_window_token), "Loaded"); + + // 5. "opener" accesses "other" window, through "openee". + send(opener_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(openee.other);") + ); + + // 6. Check a report is sent to the openee. + let report = + await receiveReport(report_token, "access-from-coop-page-to-other") + assert_equals(report.type, "coop"); + assert_equals(report.url, opener_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_found(report); + assert_equals(report.body.openerURL, undefined); + assert_equals(report.body.openeeURL, undefined); + assert_equals(report.body.otherDocumentURL, other_url.replace(/"/g, '%22')); + assert_equals(report.body.referrer, undefined); + assert_equals(report.body.initialPopupURL, undefined); +}, "access-from-coop-page-to-other (COOP-RO)"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro_cross-origin.https.html new file mode 100644 index 0000000000..f0d60c2531 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-other_coop-ro_cross-origin.https.html @@ -0,0 +1,93 @@ +<title> + One window accesses a second one. They are aren't related by an opener/openee + relationship. The first window has set + Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a + "access-from-coop-page-to-other" report. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const same_origin= get_host_info().HTTPS_ORIGIN; +const cross_origin= get_host_info().HTTPS_REMOTE_ORIGIN; + +let escapeComma = url => url.replace(/,/g, '\\,'); + +promise_test(async t => { + const report_token= token(); + const report_to = reportToHeaders(report_token); + + // The test window. + const this_window_token = token(); + + // The "opener" window. With COOP:same-origin + reporter. + const opener_token = token(); + const opener_url = same_origin + executor_path + report_to.header + + report_to.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window. With COOP:same-origin + reporter. + const openee_token = token(); + const openee_url = same_origin + executor_path + report_to.header + + report_to.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + + // The "other" window. + const other_token = token(); + const other_url = cross_origin + executor_path + report_to.header + + `&uuid=${other_token}`; + + t.add_cleanup(() => { + send(opener_token, "window.close()") + send(openee_token, "window.close()") + send(other_token, "window.close()") + }) + + // 1. Create the "opener" window. + let opener_window_proxy = window.open(opener_url); + + // 2. Create the "openee" window. + send(opener_token, ` + window.openee = window.open('${escapeComma(openee_url)}'); + `); + + // 3. Create the "other" window. + send(openee_token, ` + window.other = window.open('${escapeComma(other_url)}'); + `); + + // 4. Wait for "other" to load its document. + send(other_token, `send('${this_window_token}', "Loaded");`); + assert_equals(await receive(this_window_token), "Loaded"); + + // 5. "opener" accesses "other" window, through "openee". + + send(opener_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(openee.other);") + ); + + // 6. Check a report is sent to the openee. + let report = + await receiveReport(report_token, "access-from-coop-page-to-other") + assert_equals(report.type, "coop"); + assert_equals(report.url, opener_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_found(report); + assert_equals(report.body.openerURL, undefined); + assert_equals(report.body.openeeURL, undefined); + assert_equals(report.body.otherDocumentURL, ""); + assert_equals(report.body.referrer, undefined); +}, "access-from-coop-page-to-other (COOP-RO)"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro.https.html new file mode 100644 index 0000000000..9f0a8821a4 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro.https.html @@ -0,0 +1,77 @@ +<title> + COOP reports are to the opener when the opener used COOP-RO+COEP and then its + same-origin openee 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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const redirect_path = directory + "/resources/redirect.py?"; +const same_origin = get_host_info().HTTPS_ORIGIN; + +let runTest = (openee_redirect, name) => promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP and a reporter. + const opener_report_token= token(); + const opener_token = token(); + const opener_reportTo = reportToHeaders(opener_report_token); + const opener_url = same_origin + executor_path + opener_reportTo.header + + opener_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window. This is same origin with the "opener". + const openee_report_token= token(); + const openee_token = token(); + const openee_url = same_origin + executor_path + `&uuid=${openee_token}`; + const openee_redirect_url = same_origin + redirect_path + openee_url + const openee_requested_url = openee_redirect ? openee_redirect_url + : openee_url; + + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close()")); + + // 2. The opener opens its openee. + send(opener_token, ` + openee = window.open("${openee_requested_url}"); + send("${this_window_token}", "ACK 1"); + `); + assert_equals("ACK 1", await receive(this_window_token)); + t.add_cleanup(() => send(openee_token, "window.close()")); + + // 3. The openee tries to access its opener. + send(openee_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(opener);") + ); + + // 4. Check a report sent to the opener. + let report = + await receiveReport(opener_report_token, "access-to-coop-page-from-openee") + assert_equals(report.type, "coop"); + assert_equals(report.url, opener_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_missing(report); + assert_equals(report.body.openerURL, undefined); + assert_equals(report.body.openeeURL, openee_url); + assert_equals(report.body.otherDocumentURL, undefined); + assert_equals(report.body.referrer, undefined); + assert_equals(report.body.initialPopupURL, openee_requested_url); +}, name); + +runTest(false, "access-to-coop-page-from-openee, same-origin"); +runTest(true , "access-to-coop-page-from-openee, same-origin + redirect"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro_cross-origin.https.html new file mode 100644 index 0000000000..d9577836d9 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-openee_coop-ro_cross-origin.https.html @@ -0,0 +1,79 @@ +<title> + COOP reports are to the opener when the opener used COOP-RO+COEP and then its + cross-origin openee 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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const redirect_path = directory + "/resources/redirect.py?"; +const same_origin = get_host_info().HTTPS_REMOTE_ORIGIN; +const cross_origin= get_host_info().HTTPS_ORIGIN; + +let runTest = (openee_redirect, name) => promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP and a reporter. + const opener_report_token= token(); + const opener_token = token(); + const opener_reportTo = reportToHeaders(opener_report_token); + const opener_url = same_origin + executor_path + opener_reportTo.header + + opener_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window. This is cross origin with the "opener". + const openee_report_token= token(); + const openee_token = token(); + const openee_url = cross_origin + executor_path + `&uuid=${openee_token}`; + const openee_redirect_url = same_origin + redirect_path + openee_url + const openee_requested_url = openee_redirect ? openee_redirect_url + : openee_url; + + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close()")); + + // 2. The opener opens its openee. + send(opener_token, ` + openee = window.open("${openee_requested_url}"); + send("${this_window_token}", "ACK 1"); + `); + assert_equals("ACK 1", await receive(this_window_token)); + t.add_cleanup(() => send(openee_token, "window.close()")); + + // 3. The openee tries to access its opener. + send(openee_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(opener);") + ); + + // 4. Check a report sent to the opener. + let report = + await receiveReport(opener_report_token, "access-to-coop-page-from-openee") + assert_equals(report.type, "coop"); + assert_equals(report.url, opener_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_missing(report); + assert_equals(report.body.openerURL, undefined); + assert_equals(report.body.openeeURL, ""); + assert_equals(report.body.otherDocumentURL, undefined); + assert_equals(report.body.referrer, undefined); + assert_equals(report.body.referrer, undefined); + assert_equals(report.body.initialPopupURL, openee_requested_url); +}, name); + +runTest(false, "access-to-coop-page-from-openee, cross-origin"); +runTest(true , "access-to-coop-page-from-openee, cross-origin + redirect)"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro.https.html new file mode 100644 index 0000000000..8a643d762c --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro.https.html @@ -0,0 +1,67 @@ +<title> + COOP reports are sent when the openee used COOP-RO+COEP and then its + same-origin 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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const redirect_path = directory + "/resources/redirect.py?"; +const same_origin = get_host_info().HTTPS_ORIGIN; + +let runTest = (openee_redirect, name) => promise_test(async t => { + const report_token = token(); + const openee_token = token(); + const opener_token = token(); // The current test window. + + const opener_url = location.href; + + const reportTo = reportToHeaders(report_token); + const openee_url = same_origin + executor_path + reportTo.header + + reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + const openee_redirect_url = same_origin + redirect_path + openee_url + const openee_requested_url = openee_redirect ? openee_redirect_url + : openee_url; + + + const openee = window.open(openee_requested_url); + t.add_cleanup(() => send(openee_token, "window.close()")) + + // 1. Make sure the new document to be loaded. + send(openee_token, ` + send("${opener_token}", "Ready"); + `); + let reply = await receive(opener_token); + assert_equals(reply, "Ready"); + + // 2. Try to access the openee. A report is sent, because of COOP-RO+COEP. + tryAccess(openee); + + // 3. Check a report is sent to the openee. + let report = + await receiveReport(report_token, "access-to-coop-page-from-opener") + assert_equals(report.type, "coop"); + assert_equals(report.url, openee_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_missing(report); + assert_equals(report.body.openerURL, opener_url); + assert_equals(report.body.openeeURL, undefined); + assert_equals(report.body.otherDocumentURL, undefined); + assert_equals(report.body.referrer, opener_url); + assert_equals(report.body.initialPopupURL, undefined); +}, name); + +runTest(false, "access-to-coop-page-from-opener, same-origin"); +runTest(true , "access-to-coop-page-from-opener, same-origin + redirect"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro_cross-origin.https.html new file mode 100644 index 0000000000..7e1ae870a7 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-opener_coop-ro_cross-origin.https.html @@ -0,0 +1,68 @@ +<title> + COOP reports are sent when the openee used COOP-RO+COEP and then its + cross-origin 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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const redirect_path = directory + "/resources/redirect.py?"; +const same_origin = get_host_info().HTTPS_ORIGIN; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; + +let runTest = (openee_redirect, name) => promise_test(async t => { + const report_token = token(); + const openee_token = token(); + const opener_token = token(); // The current test window. + + const opener_origin = location.origin + '/'; + + const reportTo = reportToHeaders(report_token); + const openee_url = cross_origin + executor_path + + reportTo.header + reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + const openee_redirect_url = same_origin + redirect_path + openee_url + const openee_requested_url = openee_redirect ? openee_redirect_url + : openee_url; + + + const openee = window.open(openee_requested_url); + t.add_cleanup(() => send(openee_token, "window.close()")) + + // 1. Make sure the new document to be loaded. + send(openee_token, ` + send("${opener_token}", "Ready"); + `); + let reply = await receive(opener_token); + assert_equals(reply, "Ready"); + + // 2. Try to access the openee. A report is sent, because of COOP-RO+COEP. + tryAccess(openee); + + // 3. Check a report is sent to the openee. + let report = + await receiveReport(report_token, "access-to-coop-page-from-opener") + assert_equals(report.type, "coop"); + assert_equals(report.url, openee_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_missing(report); + assert_equals(report.body.openerURL, ""); + assert_equals(report.body.openeeURL, undefined); + assert_equals(report.body.otherDocumentURL, undefined); + assert_equals(report.body.referrer, opener_origin); + assert_equals(report.body.initialPopupURL, undefined); +}, name); + +runTest(false, "access-to-coop-page-from-opener, cross-origin"); +runTest(true , "access-to-coop-page-from-opener, cross-origin + redirect"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html new file mode 100644 index 0000000000..b73bab8610 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html @@ -0,0 +1,82 @@ +<title> + One window accesses a second one. They are aren't related by an opener/openee + relationship. The second window has set + Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a + "access-to-coop-page-from-other" report. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const same_origin = get_host_info().HTTPS_ORIGIN; + +promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. + const opener_token = token(); + const opener_url = same_origin + executor_path + `&uuid=${opener_token}`; + + // The "openee" window. With COOP:same-origin + reporter. + const openee_report_token= token(); + const openee_token = token(); + const openee_reportTo = reportToHeaders(openee_report_token); + const openee_url = same_origin + executor_path + openee_reportTo.header + + openee_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + + // The "other" window. + const other_token = token(); + const other_url = same_origin + executor_path + `&uuid=${other_token}`; + + t.add_cleanup(() => { + send(opener_token, "window.close()") + send(openee_token, "window.close()") + send(other_token, "window.close()") + }) + + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + + // 2. The opener opens its openee and the other window. + send(opener_token, ` + window.openee = window.open('${openee_url.replace(/,/g, '\\,')}'); + window.other = window.open('${other_url}'); + `); + + // 3. Make sure the openee is loaded. + send(openee_token, `send("${this_window_token}", "Loaded");`); + assert_equals(await receive(this_window_token), "Loaded"); + + // 4. The "other" window attempts to access the openee though the opener. + send(other_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(opener.openee);") + ); + + // 4. Check a report sent to the openee. + let report = + await receiveReport(openee_report_token, "access-to-coop-page-from-other") + assert_equals(report.type, "coop"); + assert_equals(report.url, openee_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_missing(report); + assert_equals(report.body.openerURL, undefined); + assert_equals(report.body.openeeURL, undefined); + assert_equals(report.body.otherDocumentURL, other_url); + assert_equals(report.body.referrer, undefined); + assert_equals(report.body.initialPopupURL, undefined); +}, "access-to-coop-page-from-other (COOP-RO)"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html new file mode 100644 index 0000000000..c86daa3dca --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro_cross-origin.https.html @@ -0,0 +1,83 @@ +<title> + One window accesses a second one. They are aren't related by an opener/openee + relationship. The second window has set + Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a + "access-to-coop-page-from-other" report. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const same_origin = get_host_info().HTTPS_ORIGIN; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; + +promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. + const opener_token = token(); + const opener_url = same_origin + executor_path + `&uuid=${opener_token}`; + + // The "openee" window. With COOP:same-origin + reporter. + const openee_report_token= token(); + const openee_token = token(); + const openee_reportTo = reportToHeaders(openee_report_token); + const openee_url = cross_origin + executor_path + openee_reportTo.header + + openee_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + + // The "other" window. + const other_token = token(); + const other_url = same_origin + executor_path + `&uuid=${other_token}`; + + t.add_cleanup(() => { + send(opener_token, "window.close()") + send(openee_token, "window.close()") + send(other_token, "window.close()") + }) + + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + + // 2. The opener opens its openee and the other window. + send(opener_token, ` + window.openee = window.open('${openee_url.replace(/,/g, '\\,')}'); + window.other = window.open('${other_url}'); + `); + + // 3. Make sure the openee is loaded. + send(openee_token, `send("${this_window_token}", "Loaded");`); + assert_equals(await receive(this_window_token), "Loaded"); + + // 4. The "other" window attempts to access the openee though the opener. + send(other_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(opener.openee);") + ); + + // 4. Check a report sent to the openee. + let report = + await receiveReport(openee_report_token, "access-to-coop-page-from-other") + assert_equals(report.type, "coop"); + assert_equals(report.url, openee_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_missing(report); + assert_equals(report.body.openerURL, undefined); + assert_equals(report.body.openeeURL, undefined); + assert_equals(report.body.otherDocumentURL, ""); + assert_equals(report.body.referrer, undefined); + assert_equals(report.body.initialPopupURL, undefined); +}, "access-to-coop-page-from-other (COOP-RO)"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-blur.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-blur.https.html new file mode 100644 index 0000000000..849bf6579a --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-blur.https.html @@ -0,0 +1,13 @@ +<title> Check openee.blur() access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("blur", w => w.blur()); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-close.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-close.https.html new file mode 100644 index 0000000000..7696600488 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-close.https.html @@ -0,0 +1,13 @@ +<title> Check openee.close() access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("close", w => w.close()); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-closed.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-closed.https.html new file mode 100644 index 0000000000..c678d18a80 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-closed.https.html @@ -0,0 +1,13 @@ +<title> Check openee.closed access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("closed", w => w.closed); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-focus.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-focus.https.html new file mode 100644 index 0000000000..363c0d294f --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-focus.https.html @@ -0,0 +1,13 @@ +<title> Check openee.focus() access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("focus", w => w.focus()); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-frames.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-frames.https.html new file mode 100644 index 0000000000..fc1925045f --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-frames.https.html @@ -0,0 +1,13 @@ +<title> Check openee.frames access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("frames", w => w.frames); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html new file mode 100644 index 0000000000..b6c5f5acb1 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html @@ -0,0 +1,66 @@ +<title> Check reports are sent for the indexed getter</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="/common/dispatcher/dispatcher.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const executor_path = "/common/dispatcher/executor.html?pipe="; +const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)'; + +let origin = [ + ["cross-origin" , get_host_info().HTTPS_REMOTE_ORIGIN ] , + ["same-site" , get_host_info().HTTPS_ORIGIN ] , +]; + +let testCase = [ +//[operation , expectReport ] , + [w => w[0] , true ], // Existing iframe. + [w => w[1] , false ], // Out of bounds (positive). + [w => w[-1] , false ], // Out of bounds (negative). +]; + +origin.forEach(([origin_name, origin]) => { + testCase.forEach(([op, expectReport]) => { + promise_test(async t => { + const opener_token = token(); + const openee_token = token(); + + const openee_url = origin+ executor_path + `&uuid=${openee_token}`; + const openee = window.open(openee_url); + t.add_cleanup(() => send(openee_token, "window.close()")) + + // 1. Create an iframe in the openee. + send(openee_token, ` + let iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + + send("${opener_token}", "openee loaded"); + `); + let reply = await receive(opener_token); + assert_equals(reply, "openee loaded"); + + // 2. Try to access the openee. + let observer = new ReportingObserver(()=>{}); + observer.observe(); + try {op(openee)} catch(e) {} + let reports = observer.takeRecords(); + observer.disconnect(); + + // 3. Check the received reports. + if (expectReport) { + assert_equals(reports.length, 1); + assert_equals(reports[0].type, "coop-access-violation"); + assert_equals(reports[0].body.property, "indexed"); + } else { + assert_equals(reports.length, 0); + } + + }, `${origin_name} > ${op}`); +}); +}); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html.headers new file mode 100644 index 0000000000..64f4d5fedf --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-indexed-getter.https.html.headers @@ -0,0 +1 @@ +Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="none" diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-length.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-length.https.html new file mode 100644 index 0000000000..a9f3614cb5 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-length.https.html @@ -0,0 +1,13 @@ +<title> Check openee.length access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("length", w => w.length); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-get.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-get.https.html new file mode 100644 index 0000000000..442817748d --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-get.https.html @@ -0,0 +1,13 @@ +<title> Check openee.location access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("location", w => w.location); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-set.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-set.https.html new file mode 100644 index 0000000000..e42f084821 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-location-set.https.html @@ -0,0 +1,13 @@ +<title> Check openee.location access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("location", w => w.location = "#"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html new file mode 100644 index 0000000000..27be9a48d1 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html @@ -0,0 +1,71 @@ +<title> Check reports are sent for the indexed getter</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="/common/dispatcher/dispatcher.js"></script> +<script> + +const executor_path = "/common/dispatcher/executor.html?pipe="; +let crossOrigin = ["cross-origin" , get_host_info().HTTPS_REMOTE_ORIGIN ]; +let sameOrigin = ["same-site" , get_host_info().HTTPS_ORIGIN ]; + +let testCase = [ +//[ operation , origin , expectReport ], + [ w => w["iframeName"] , sameOrigin , true ], + [ w => w["iframeName"] , crossOrigin , true ], + [ w => w["divID"] , sameOrigin , true ], + [ w => w["divID"] , crossOrigin , false ], + [ w => w["existingGlobal"] , sameOrigin , false ], + [ w => w["existingGlobal"] , crossOrigin , false ], + [ w => w["missingGlobal"] , sameOrigin , false ], + [ w => w["missingGlobal"] , crossOrigin , false ], +]; + +testCase.forEach(([op, [origin_name, origin], expectReport]) => { + promise_test(async t => { + const opener_token = token(); + const openee_token = token(); + + const openee_url = origin + executor_path + `&uuid=${openee_token}`; + const openee = window.open(openee_url); + t.add_cleanup(() => send(openee_token, "window.close()")) + + // 1. Make sure the new document to be loaded. Populate the document. + send(openee_token, ` + let iframe = document.createElement("iframe"); + iframe.name = "iframeName"; + document.body.appendChild(iframe); + + let div = document.createElement("div"); + div.id = "divID"; + document.body.appendChild(div); + + window.existingGlobal = "test"; + + send("${opener_token}", "Ready"); + `); + let reply = await receive(opener_token); + assert_equals(reply, "Ready"); + + // 2. Try to access the openee. + let observer = new ReportingObserver(()=>{}); + observer.observe(); + try {op(openee)} catch(e) {} + let reports = observer.takeRecords(); + observer.disconnect(); + + // 3. Check the received reports. + if (expectReport) { + assert_equals(reports.length, 1); + assert_equals(reports[0].type, "coop-access-violation"); + assert_equals(reports[0].body.property, "named"); + } else { + assert_equals(reports.length, 0); + } + + }, `${origin_name} > ${op}`); +}); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html.headers new file mode 100644 index 0000000000..64f4d5fedf --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-named-getter.https.html.headers @@ -0,0 +1 @@ +Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="none" diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-get.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-get.https.html new file mode 100644 index 0000000000..b99dfdc562 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-get.https.html @@ -0,0 +1,13 @@ +<title> Check openee.opener access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("opener", w => w.opener); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-set.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-set.https.html new file mode 100644 index 0000000000..10c251140b --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-opener-set.https.html @@ -0,0 +1,13 @@ +<title> Check openee.opener access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("opener", w => w.opener = "", /* expectReport = */false); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-1.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-1.https.html new file mode 100644 index 0000000000..a9168fdaa5 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-1.https.html @@ -0,0 +1,13 @@ +<title> Check openee.postMessage(arg1, arg2) access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("postMessage", w => w.postMessage("", "")); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-2.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-2.https.html new file mode 100644 index 0000000000..4341f245d5 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-postmessage-2.https.html @@ -0,0 +1,13 @@ +<title> Check openee.postMessage(arg1) access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("postMessage", w => w.postMessage("")); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-self.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-self.https.html new file mode 100644 index 0000000000..7a7d5a3fec --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-self.https.html @@ -0,0 +1,13 @@ +<title> Check openee.self access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("self", w => w.self); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-top.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-top.https.html new file mode 100644 index 0000000000..1b75ecc105 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-top.https.html @@ -0,0 +1,13 @@ +<title> Check openee.top access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("top", w => w.top); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-window.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-window.https.html new file mode 100644 index 0000000000..07278b4a11 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/property-window.https.html @@ -0,0 +1,13 @@ +<title> Check openee.window access is checked</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/test-access-property.js"></script> +<script> + +testAccessProperty("window", w => w.window); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/report-to-both_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/report-to-both_coop-ro.https.html new file mode 100644 index 0000000000..46cdc6eb27 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/report-to-both_coop-ro.https.html @@ -0,0 +1,124 @@ +<title> + Both the openee and the opener have a COOP reporter. The report are sent to + both side. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const origin_opener = get_host_info().HTTPS_ORIGIN; +const origin_openee = get_host_info().HTTPS_REMOTE_ORIGIN; + +let escapeComma = url => url.replace(/,/g, '\\,'); + +let genericSetup = async function(test) { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP and a reporter. + const opener_report_token= token(); + const opener_token = token(); + const opener_reportTo = reportToHeaders(opener_report_token); + const opener_url = origin_opener+ executor_path + opener_reportTo.header + + opener_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window. This has COOP and a reporter. + const openee_report_token= token(); + const openee_token = token(); + const openee_reportTo = reportToHeaders(openee_report_token); + const openee_url = origin_openee + executor_path + openee_reportTo.header + + openee_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + + // Cleanup at the end of the test. + test.add_cleanup(() => { + send(openee_token, 'window.close()'); + send(opener_token, 'window.close()'); + }); + + // 1. Spawn the opener and the openee windows. + window.open(opener_url); + send(opener_token, ` + openee = window.open('${escapeComma(openee_url)}'); + `); + + // 2. Wait for both to be loaded. + send(openee_token, `send('${this_window_token}', 'ACK');`); + assert_equals(await receive(this_window_token), 'ACK'); + + return [ + this_window_token, + opener_token, opener_report_token, opener_url, + openee_token, openee_report_token, openee_url, + ]; +} + +let assert_generic_coop_report = function(report) { + assert_equals(report.type, "coop"); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); +} + +promise_test(async test => { + let [ + this_window_token, + opener_token, opener_report_token, opener_url, + openee_token, openee_report_token, openee_url, + ] = await genericSetup(test); + + send(opener_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(openee);") + ); + + let report_opener = + await receiveReport(opener_report_token, "access-from-coop-page-to-openee") + let report_openee = + await receiveReport(openee_report_token, "access-to-coop-page-from-opener") + + assert_generic_coop_report(report_openee); + assert_generic_coop_report(report_opener); + + assert_equals(report_opener.url, opener_url.replace(/"/g, '%22')); + assert_equals(report_openee.url, openee_url.replace(/"/g, '%22')); + assert_source_location_found(report_opener); + assert_source_location_missing(report_openee); +}, "Access from opener") + +promise_test(async test => { + let [ + this_window_token, + opener_token, opener_report_token, opener_url, + openee_token, openee_report_token, openee_url, + ] = await genericSetup(test); + + send(openee_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(opener);") + ); + + let report_opener = + await receiveReport(opener_report_token, "access-to-coop-page-from-openee") + let report_openee = + await receiveReport(openee_report_token, "access-from-coop-page-to-opener") + + assert_generic_coop_report(report_openee); + assert_generic_coop_report(report_opener); + + assert_equals(report_opener.url, opener_url.replace(/"/g, '%22')); + assert_equals(report_openee.url, openee_url.replace(/"/g, '%22')); + assert_source_location_missing(report_opener); + assert_source_location_found(report_openee); +}, "Access from openee") + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html new file mode 100644 index 0000000000..375c627d27 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html @@ -0,0 +1,275 @@ +<!doctype html> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<title> + Check the ReportingObserver(s) are notified about the coop-access-violation + events. +</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const same_origin = get_host_info().HTTPS_ORIGIN; +const cross_site = get_host_info().HTTPS_NOTSAMESITE_ORIGIN; +const corp_header = '|header(Cross-Origin-Resource-Policy,cross-origin)'; + +promise_test(async t => { + // This test window. + const this_window_token = token(); + + // The "opener" window, using COOP-Report-Only and a reporter. + const opener_token = token(); + const opener_reportTo = reportToHeaders(token()); + const opener_url = same_origin + executor_path + opener_reportTo.header + + opener_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window, NOT using COOP. + const openee_token = token(); + const openee_url = same_origin + executor_path + `&uuid=${openee_token}`; + + // 1. Create the opener window. + window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close();")); + + // 2. The opener opens its openee. + send(opener_token, `openee = window.open('${openee_url}');`); + t.add_cleanup(() => send(openee_token, `window.close();`)); + + // 3. Wait for the openee to load its document. + send(openee_token, `send("${this_window_token}", "Ready");`); + assert_equals(await receive(this_window_token), "Ready"); + + // 4. The opener tries to access its openee. All reports for blocked access + // from the COOP page should notify the ReportingObservers. + send(opener_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", ` + let observer = new ReportingObserver(()=>{}); + observer.observe(); + tryAccess(openee); + let reports = observer.takeRecords(); + send("${this_window_token}", JSON.stringify(reports)); + observer.disconnect(); + `)); + + let report_access_from = JSON.parse(await receive(this_window_token)); + assert_equals(report_access_from.length, 1, "No report received."); + assert_equals(report_access_from[0].type, "coop-access-violation"); + assert_equals(report_access_from[0].url, opener_url.replace(/"/g, '%22')); + assert_source_location_found(report_access_from[0]) + assert_equals(report_access_from[0].body.type, + "access-from-coop-page-to-openee"); + assert_equals(report_access_from[0].body.openeeURL, openee_url); + assert_equals(report_access_from[0].body.openerURL, undefined); + assert_equals(report_access_from[0].body.otherDocumentURL, undefined); + + // 5. The openee tries to access its opener. No reports for blocked access + // to the COOP page should be dispatched. + send(openee_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", ` + let observer = new ReportingObserver(()=>{}); + observer.observe(); + tryAccess(opener); + let reports = observer.takeRecords(); + send("${this_window_token}", JSON.stringify(reports)); + observer.disconnect(); + `)); + let report_access_to = JSON.parse(await receive(this_window_token)); + assert_equals(report_access_to.length, 0, "Unexpected report received."); +}, "Opener COOP"); + +promise_test(async t => { + // This test window. + const this_window_token = token(); + + // The "opener" window, NOT using COOP. + const opener_token = token(); + const opener_url = same_origin + executor_path + `&uuid=${opener_token}`; + + // The "openee" window, using COOP-Report-Only and a reporter. + const openee_token = token(); + const openee_reportTo = reportToHeaders(token()); + const openee_url = same_origin + executor_path + openee_reportTo.header + + openee_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + + // 1. Create the opener window. + window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close();")); + + // 2. The opener opens its openee. + send(opener_token, + `openee = window.open('${openee_url.replace(/,/g, '\\,')}');`); + t.add_cleanup(() => send(openee_token, `window.close();`)); + + // 3. The openee tries to access its opener. All reports for blocked access + // from the COOP page should notify the ReportingObservers. + send(openee_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", ` + let observer = new ReportingObserver(()=>{}); + observer.observe(); + tryAccess(opener); + let reports = observer.takeRecords(); + send("${this_window_token}", JSON.stringify(reports)); + observer.disconnect(); + `)); + let report_access_from = JSON.parse(await receive(this_window_token)); + assert_equals(report_access_from.length, 1, "No report received."); + assert_equals(report_access_from[0].type, "coop-access-violation"); + assert_equals(report_access_from[0].url, openee_url.replace(/"/g, '%22')); + assert_true(report_access_from[0].body.sourceFile.includes("try-access.js")); + assert_source_location_found(report_access_from[0]) + assert_equals(report_access_from[0].body.type, + "access-from-coop-page-to-opener"); + assert_equals(report_access_from[0].body.openeeURL, undefined); + assert_equals(report_access_from[0].body.openerURL, opener_url); + assert_equals(report_access_from[0].body.otherDocumentURL, undefined); + + // 4. The opener tries to access its openee. No reports for blocked access + // to the COOP page should be dispatched. + send(opener_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", ` + let observer = new ReportingObserver(()=>{}); + observer.observe(); + tryAccess(openee); + let reports = observer.takeRecords(); + send("${this_window_token}", JSON.stringify(reports)); + observer.disconnect(); + `)); + let report_access_to = JSON.parse(await receive(this_window_token)); + assert_equals(report_access_to.length, 0, "Unexpected report received."); +}, "Openee COOP"); + +promise_test(async t => { + // This test window. + const this_window_token = token(); + + // The "opener" window, using COOP-Report-Only and a reporter. + const opener_token = token(); + const opener_reportTo = reportToHeaders(token()); + const opener_url = same_origin + executor_path + opener_reportTo.header + + opener_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "opener's iframe", same-origin with its parent. + const opener_iframe_token = token(); + const opener_iframe_url = same_origin + executor_path + coep_header + + `&uuid=${opener_iframe_token}`; + + // The "openee" window, NOT using COOP. + const openee_token = token(); + const openee_url = same_origin + executor_path + coep_header + + `&uuid=${openee_token}`; + + // 1. Create the opener window. + window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close();")); + + // 2. The opener opens an iframe, and install a ReportingObserver to catch + // future accesses. + send(opener_token, ` + iframe = document.createElement("iframe"); + iframe.src = "${opener_iframe_url}"; + document.body.appendChild(iframe); + + let observer = new ReportingObserver(reports => { + send("${this_window_token}", JSON.stringify(reports)); + observer.disconnect(); + }); + observer.observe(); + `); + + // 3. The iframe opens the openee. + send(opener_iframe_token, `openee = window.open('${openee_url}');`); + t.add_cleanup(() => send(openee_token, `window.close();`)); + + // 4. Wait for the openee to load its document. + send(openee_token, `send("${this_window_token}", "Ready");`); + assert_equals(await receive(this_window_token), "Ready"); + + // 4. The opener's iframe tries to access the openee. This is an + // "access-from-coop-page" from a same-origin iframe, so the + // ReportingObserver(s) are notified. + send(opener_iframe_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", `tryAccess(openee);`)); + + let reports = await receive(this_window_token); + reports = JSON.parse(reports); + assert_equals(reports.length, 1, "No report received."); + assert_equals(reports[0].type, "coop-access-violation"); + assert_equals(reports[0].url, opener_url.replace(/"/g, '%22')); + assert_true(reports[0].body.sourceFile.includes("try-access.js")); + assert_source_location_found(reports[0]); + assert_equals(reports[0].body.type, + "access-from-coop-page-to-openee"); + assert_equals(reports[0].body.openeeURL, openee_url); + assert_equals(reports[0].body.openerURL, undefined); + assert_equals(reports[0].body.otherDocumentURL, undefined); +}, "Access from same-origin iframe") + +promise_test(async t => { + // This test window. + const this_window_token = token(); + + // The "opener" window, using COOP-Report-Only and a reporter. + const opener_token = token(); + const opener_reportTo = reportToHeaders(token()); + const opener_url = same_origin + executor_path + opener_reportTo.header + + opener_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "opener's iframe", same-origin with its parent. + const opener_iframe_token = token(); + const opener_iframe_url = cross_site + executor_path + coep_header + + corp_header + + `&uuid=${opener_iframe_token}`; + + // The "openee" window, NOT using COOP. + const openee_token = token(); + const openee_url = same_origin + executor_path + coep_header + + `&uuid=${openee_token}`; + + // 1. Create the opener window. + window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close();")); + + // 2. The opener opens an iframe, and install a ReportingObserver to catch + // future accesses. + send(opener_token, ` + iframe = document.createElement("iframe"); + iframe.src = "${opener_iframe_url}"; + document.body.appendChild(iframe); + + let observer = new ReportingObserver(reports => { + send("${this_window_token}", JSON.stringify(reports)); + observer.disconnect(); + }); + observer.observe(); + `); + + // 3. The iframe opens the openee. + send(opener_iframe_token, `openee = window.open('${openee_url}');`); + t.add_cleanup(() => send(openee_token, `window.close();`)); + + // 4. Wait for the openee to load its document. + send(openee_token, `send("${this_window_token}", "Ready");`); + assert_equals(await receive(this_window_token), "Ready"); + + // 5. The opener's iframe tries to access the openee. This is an + // "access-from-coop-page" from a cross-site iframe. The ReportingObservers + // from the main document aren't notified. + send(opener_iframe_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", `tryAccess(openee);`)); + + let reports = await receive(this_window_token, 2000); + assert_equals(reports, "timeout", "Unexpected report received."); +}, "Access from cross-site iframe") + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html new file mode 100644 index 0000000000..7bfdab1330 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html @@ -0,0 +1,86 @@ + +<meta name=timeout content=long> +<title>A test with both COOP and COOP report only setup using Reporting-Endpoints header</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script + src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=2aee31d2-cd11-43bd-b34d-5f081ca3b2b4&report_only_id=d18f1779-e2ab-4a7a-8b1c-44e3a6f440f5"></script> + +<script> +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports + + // Open a cross-origin popup with both normal and report-only COOP. Four + // reports are sent. + [ + CROSS_ORIGIN, + `same-origin-allow-popups; report-to="${popupReportEndpoint.name}"`, + "require-corp", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "require-corp", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-allow-popups", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": reportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin-plus-coep", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-allow-popups", + "previousResponseURL": "", + "referrer": `${location.origin}/`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + }, + { + "endpoint": popupReportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin-plus-coep", + "previousResponseURL": "", + "referrer": `${location.origin}/`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ] +]; + +runNavigationDocumentReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html.sub.headers new file mode 100644 index 0000000000..de48445f38 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-only-four-reports.https.html.sub.headers @@ -0,0 +1,6 @@ +Cross-Origin-Opener-Policy: same-origin-allow-popups; report-to="coop-report-endpoint" +Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop-report-only-endpoint" +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Embedder-Policy-Report-Only: require-corp +Referrer-Policy: origin +Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=2aee31d2-cd11-43bd-b34d-5f081ca3b2b4", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=d18f1779-e2ab-4a7a-8b1c-44e3a6f440f5" diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-to-both_coop-ro.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-to-both_coop-ro.https.html new file mode 100644 index 0000000000..409628c15c --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/report-to-both_coop-ro.https.html @@ -0,0 +1,124 @@ +<title> + Both the openee and the opener have a COOP reporter. The report are sent to + both side. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const origin_opener = get_host_info().HTTPS_ORIGIN; +const origin_openee = get_host_info().HTTPS_REMOTE_ORIGIN; + +let escapeComma = url => url.replace(/,/g, '\\,'); + +let genericSetup = async function(test) { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP and a reporter. + const opener_token = token(); + const opener_report_token = reportToken(); + const opener_reporting = reportingEndpointsHeaders(opener_report_token); + const opener_url = origin_opener+ executor_path + opener_reporting.header + + opener_reporting.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${opener_token}`; + + // The "openee" window. This has COOP and a reporter. + const openee_token = token(); + const openee_report_token = reportToken(); + const openee_reporting = reportingEndpointsHeaders(openee_report_token); + const openee_url = origin_openee + executor_path + openee_reporting.header + + openee_reporting.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + + // Cleanup at the end of the test. + test.add_cleanup(() => { + send(openee_token, 'window.close()'); + send(opener_token, 'window.close()'); + }); + + // 1. Spawn the opener and the openee windows. + window.open(opener_url); + send(opener_token, ` + openee = window.open('${escapeComma(openee_url)}'); + `); + + // 2. Wait for both to be loaded. + send(openee_token, `send('${this_window_token}', 'ACK');`); + assert_equals(await receive(this_window_token), 'ACK'); + + return [ + this_window_token, + opener_token, opener_report_token, opener_url, + openee_token, openee_report_token, openee_url, + ]; +} + +let assert_generic_coop_report = function(report) { + assert_equals(report.type, "coop"); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); +} + +promise_test(async test => { + let [ + this_window_token, + opener_token, opener_report_token, opener_url, + openee_token, openee_report_token, openee_url, + ] = await genericSetup(test); + + send(opener_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(openee);") + ); + + let report_opener = + await receiveReport(opener_report_token, "access-from-coop-page-to-openee") + let report_openee = + await receiveReport(openee_report_token, "access-to-coop-page-from-opener") + + assert_generic_coop_report(report_openee); + assert_generic_coop_report(report_opener); + + assert_equals(report_opener.url, opener_url.replace(/"/g, '%22')); + assert_equals(report_openee.url, openee_url.replace(/"/g, '%22')); + assert_source_location_found(report_opener); + assert_source_location_missing(report_openee); +}, "Access from opener") + +promise_test(async test => { + let [ + this_window_token, + opener_token, opener_report_token, opener_url, + openee_token, openee_report_token, openee_url, + ] = await genericSetup(test); + + send(openee_token, addScriptAndTriggerOnload( + directory + "/reporting/resources/try-access.js", + "tryAccess(opener);") + ); + + let report_opener = + await receiveReport(opener_report_token, "access-to-coop-page-from-openee") + let report_openee = + await receiveReport(openee_report_token, "access-from-coop-page-to-opener") + + assert_generic_coop_report(report_openee); + assert_generic_coop_report(report_opener); + + assert_equals(report_opener.url, opener_url.replace(/"/g, '%22')); + assert_equals(report_openee.url, openee_url.replace(/"/g, '%22')); + assert_source_location_missing(report_opener); + assert_source_location_found(report_openee); +}, "Access from openee") + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-same-origin-allow-popups.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-same-origin-allow-popups.https.html new file mode 100644 index 0000000000..b2ff818d56 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-same-origin-allow-popups.https.html @@ -0,0 +1,111 @@ +<title> + Tests the redirect interaction with COOP same-origin-allow-popups. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script> + +const same_origin = { + host: get_host_info().HTTPS_ORIGIN, + name: "Same origin" +}; +const cross_origin = { + host: get_host_info().HTTPS_REMOTE_ORIGIN, + name: "Cross origin" +}; + +// Tests the redirect interaction with COOP same-origin-allow-popups and +// reporting: +// 1 - open the opener document on origin same_origin wit COOP +// same-origin-allow-popups. +// 2 - opener opens popup with document on origin popup_origin, no COOP and a +// redirect header (HTTP 302, location). +// 3 - redirection to a document with origin same_origin and COOP +// same-origin-allow-popups. +// +// The navigation (2) to the first document of the popup stays in the same +// browsing context group due to the same-origin-allow-popups COOP of the +// opener. +// The redirect (3) to the final document does since it compares the +// popup_origin/unsafe-none document with the +// same-origin/same-origin-allow-popups document. +// +// A opens B, B redirects to C. +// +// Document Origin COOP +// -------- ------------ ------------------------ +// A same-origin same-origin-allow-popups +// B popup-origin unsafe-none +// C same-origin same-origin-allow-popups +function redirect_test(popup_origin) { + promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP same-origin-allow-popups and a + // reporter. + const opener_token = token(); + const opener_report_token = reportToken(); + const opener_reporting = reportingEndpointsHeaders(opener_report_token); + const opener_url = same_origin.host + executor_path + + opener_reporting.header + opener_reporting.coopSameOriginAllowPopupsHeader + + `&uuid=${opener_token}`; + + // The "openee" window. + // The initial document does not have COOP and is on popup_origin, it + // redirects to a same-origin (with the opener) document with COOP + // same-origin-allow-popups. + const openee_token = token(); + const openee_redirect_url = same_origin.host + executor_path + + opener_reporting.header + opener_reporting.coopSameOriginAllowPopupsHeader + + `&uuid=${openee_token}`; + const redirect_header = 'status(302)' + + `|header(Location,${encodeURIComponent( + openee_redirect_url + .replace(/,/g, "\\,") + .replace(/\\\\,/g, "\\\\\\,") + .replace(/\(/g, "%28") + .replace(/\)/g, "%29"))})`; + const openee_url = popup_origin.host + executor_path + redirect_header + + `&uuid=${openee_token}`; + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close()")); + + // 2. The opener opens its openee. + send(opener_token, ` + openee = window.open("${openee_url}"); + `); + t.add_cleanup(() => send(openee_token, "window.close()")); + + // 3. Check the opener status on the openee. + send(openee_token, ` + send("${this_window_token}", opener !== null); + `); + assert_equals(await receive(this_window_token), "false", "opener"); + + // 4. Check the openee status on the opener. + send(opener_token, ` + send("${this_window_token}", openee.closed); + `); + assert_equals(await receive(this_window_token), "true", "openee.closed"); + + // 5. Check a report sent to the openee. + let report = await receiveReport( + opener_report_token, + "navigation-to-response"); + assert_equals(report.type, "coop"); + assert_equals(report.body.disposition, "enforce"); + assert_equals(report.body.effectivePolicy, "same-origin-allow-popups"); + }, `${popup_origin.name} openee redirected to same-origin with same-origin-allow-popups`); +} + +redirect_test(same_origin); +redirect_test(cross_origin); +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-unsafe-none.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-unsafe-none.https.html new file mode 100644 index 0000000000..bd89856305 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/document-reporting/reporting-redirect-with-unsafe-none.https.html @@ -0,0 +1,130 @@ +<title> + Tests the redirect interaction with COOP unsafe-none. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script> + +const same_origin = { + host: get_host_info().HTTPS_ORIGIN, + name: "Same origin" +}; +const cross_origin = { + host: get_host_info().HTTPS_REMOTE_ORIGIN, + name: "Cross origin" +}; + +// Repeated call receive() to fetch all reports received within 1 second. +async function fetchReportsByID(uuid){ + let timeStart = new Date().getTime(); + const reports = []; + while(new Date().getTime() - timeStart < 1000) { + // Promise.race is used to timeout since receive() has no timeout mechanism. + reports.push(...await Promise.race([ + receive(uuid).then(JSON.parse), + new Promise(resolve => step_timeout(resolve, 1000, [])) + ])); + } + return reports; +} + +function fetchReportByType(reports, type){ + return reports.filter((report)=> (report.body.type === type)); +} + + // Tests the redirect interaction with COOP unsafe-none and reporting: + // 1 - open the opener document on origin same_origin with COOP + // unsafe-none. + // 2 - opener opens popup with document on origin popup_origin, with COOP + // same-origin, Reporting-Endpoints header and a redirect header + // (HTTP 302, location). + // 3 - redirection to a document with origin same-origin and COOP + // unsafe-none. + // + // Navigation 2) should generate a report sent to B's reporter(navigation-to). + // Navigation 3) should generate a report sent to B's reporter(navigation-from). + // + // A opens B, B redirects to C. + // + // Document Origin COOP + // -------- ------------ ------------------------ + // A same-origin unsafe-none + // B popup-origin same-origin + // C same-origin unsafe-none +function redirect_test(popup_origin) { + promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP unsafe-none and no reporter. + const opener_token = token(); + const opener_url = same_origin.host + executor_path + + `&uuid=${opener_token}`; + + // The "openee" window. + // The initial document have COOP, reporter and is on popup_origin, it + // redirects to a same-origin (with the opener) document with no COOP. + const openee_token = token(); + const openee_report_token = reportToken(); + const openee_reporting = reportingEndpointsHeaders(openee_report_token); + const openee_redirect_url = same_origin.host + executor_path + + `&uuid=${openee_token}`; + const redirect_header = '|status(302)' + + `|header(Location,${encodeURIComponent( + openee_redirect_url)})`; + const openee_url = (popup_origin.host + executor_path + + openee_reporting.header + openee_reporting.coopSameOriginHeader + + redirect_header + `&uuid=${openee_token}`) + .replace(/,/g, "\\,") + .replace(/\\\\,/g, "\\\\\\,") + .replace(/\(/g, "%28") + .replace(/\)/g, "%29"); + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close()")); + + // 2. The opener opens its openee. + send(opener_token, ` + openee = window.open(\`${openee_url}\`); + `); + t.add_cleanup(() => send(openee_token, "window.close()")); + + // 3. Check the opener status on the openee. + send(openee_token, ` + send("${this_window_token}", opener !== null); + `); + assert_equals(await receive(this_window_token), "false", "opener"); + + // 4. Check the openee status on the opener. + send(opener_token, ` + send("${this_window_token}", openee.closed); + `); + assert_equals(await receive(this_window_token), "true", "openee.closed"); + + // 5. Check a report sent to B's reporting endpoint when A opens B. + const reports = await fetchReportsByID(openee_report_token); + const navigationToReport = fetchReportByType( + reports, "navigation-to-response"); + assert_equals(navigationToReport.length, 1); + assert_equals(navigationToReport[0].type, "coop"); + assert_equals(navigationToReport[0].body.disposition, "enforce"); + assert_equals(navigationToReport[0].body.effectivePolicy, "same-origin"); + // 6. Check a report sent to B's reporting endpoint when B redirects to C. + const navigationFromReport = fetchReportByType( + reports, "navigation-from-response"); + assert_equals(navigationFromReport.length, 1); + assert_equals(navigationFromReport[0].type, "coop"); + assert_equals(navigationFromReport[0].body.disposition, "enforce"); + assert_equals(navigationFromReport[0].body.effectivePolicy, "same-origin"); + }, `${popup_origin.name} openee redirected to same-origin with unsafe-none`); +} + +redirect_test(same_origin); +redirect_test(cross_origin); +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html new file mode 100644 index 0000000000..ca1471ccc0 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html @@ -0,0 +1,86 @@ +<meta name=timeout content=long> +<title>A test with both COOP and COOP report only setup</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script + src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=47b45e17-51c5-4691-bdd5-8f343bbfcf42&report_only_id=3eb3ad1d-872e-4ea8-8b40-0e98783a0683"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports + + // Open a cross-origin popup with both normal and report-only COOP. Four + // reports are sent. + [ + CROSS_ORIGIN, + `same-origin-allow-popups; report-to="${popupReportEndpoint.name}"`, + "require-corp", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "require-corp", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-allow-popups", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": reportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin-plus-coep", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-allow-popups", + "previousResponseURL": "", + "referrer": `${location.origin}/`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + }, + { + "endpoint": popupReportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin-plus-coep", + "previousResponseURL": "", + "referrer": `${location.origin}/`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ] +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html.sub.headers new file mode 100644 index 0000000000..50c3045bb6 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-four-reports.https.html.sub.headers @@ -0,0 +1,6 @@ +Cross-Origin-Opener-Policy: same-origin-allow-popups; report-to="coop-report-endpoint" +Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop-report-only-endpoint" +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Embedder-Policy-Report-Only: require-corp +Referrer-Policy: origin +Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=47b45e17-51c5-4691-bdd5-8f343bbfcf42", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=3eb3ad1d-872e-4ea8-8b40-0e98783a0683"
\ No newline at end of file diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html new file mode 100644 index 0000000000..cca2e7e1ae --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html @@ -0,0 +1,71 @@ + +<meta name=timeout content=long> +<title>Report only tests for an opener without any COOP/COOP report only set</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports + + // Open a same-origin popup with a same-origin COOP report-only value, which + // would cause a browsing context group swap, hence a report is sent. + [ + SAME_ORIGIN, + "", + "", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "", + [ + { + "endpoint": popupReportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin", + "previousResponseURL": `${location.href}`, // previous documnent url + "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with a same-origin COOP report-only value, which + // would cause a browsing context group swap, hence a report is sent. + [ + CROSS_ORIGIN, + "", + "", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "", + [ + { + "endpoint": popupReportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin", + "previousResponseURL": "", + "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.headers new file mode 100644 index 0000000000..5b29739bbd --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.headers @@ -0,0 +1 @@ +Referrer-Policy: origin diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html new file mode 100644 index 0000000000..52b1f2a09f --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html @@ -0,0 +1,96 @@ +<meta name=timeout content=long> +<title>reporting same origin with report-to</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script + src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=380ca360-d1ae-4329-b1dd-69cea49cd705&report_only_id=cf9ac91d-6c5d-4489-a420-10be9402ef84"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports + + // Open a cross-origin popup without any COOP setup, the current document + // (opener) report-only would cause a browsing context group swap, hence a + // report is sent to the corresponding endpoint. + [ + CROSS_ORIGIN, + "", + "", + "", + "", + [ + { + "endpoint": reportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + ] + ], + // Open a cross-origin popup with a same-origin COOP report-only value, which + // would cause a browsing context group swap, hence a report is sent to both + // endpoints. + [ + CROSS_ORIGIN, + "", + "", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "", + [ + { + "endpoint": reportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin", + "previousResponseURL": "", + "referrer": `${location.origin}/`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a same-origin popup with a same-origin COOP report-only value, the two + // COOP-report-only values match, hence no virtual browsing context group swap + // happens and no report is sent. + [ + SAME_ORIGIN, + "", + "", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "", + [] + ], +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.sub.headers new file mode 100644 index 0000000000..04bc49906b --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.sub.headers @@ -0,0 +1,3 @@ +Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop-report-only-endpoint" +Referrer-Policy: origin +Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=380ca360-d1ae-4329-b1dd-69cea49cd705", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=cf9ac91d-6c5d-4489-a420-10be9402ef84" diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html new file mode 100644 index 0000000000..148c700ee5 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html @@ -0,0 +1,32 @@ + +<meta name=timeout content=long> +<title>reporting same origin with report-to</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports + + // Open a cross-origin popup with COOP report-only with coep, which mismatches + // with the current document (opener) COOP (unsafe-none) and COOP report-only + // (same-origin) values. + [ + SAME_ORIGIN, + "", + "require-corp", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "", + [] + ], +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html.headers new file mode 100644 index 0000000000..58ab03394a --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep-report-only.https.html.headers @@ -0,0 +1,3 @@ +Cross-Origin-Opener-Policy-Report-Only: same-origin +Cross-Origin-Embedder-Policy-Report-Only: require-corp +Referrer-Policy: origin diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html new file mode 100644 index 0000000000..148c700ee5 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html @@ -0,0 +1,32 @@ + +<meta name=timeout content=long> +<title>reporting same origin with report-to</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports + + // Open a cross-origin popup with COOP report-only with coep, which mismatches + // with the current document (opener) COOP (unsafe-none) and COOP report-only + // (same-origin) values. + [ + SAME_ORIGIN, + "", + "require-corp", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "", + [] + ], +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html.headers new file mode 100644 index 0000000000..2ba7ffb592 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-with-coep.https.html.headers @@ -0,0 +1,3 @@ +Cross-Origin-Opener-Policy-Report-Only: same-origin +Cross-Origin-Embedder-Policy: require-corp +Referrer-Policy: origin diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html new file mode 100644 index 0000000000..8a63682c69 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html @@ -0,0 +1,73 @@ + +<meta name=timeout content=long> +<title>reporting same origin with report-to</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report-only, popup COEP report-only, expected reports + + // Open a cross-origin popup with COOP report-only with coep, which mismatches + // with the current document (opener) COOP (unsafe-none) and COOP report-only + // (same-origin) values. + [ + SAME_ORIGIN, + "", + "require-corp", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "", + [ + { + "endpoint": popupReportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin-plus-coep", + "previousResponseURL": `${location.href}`, + "referrer": `${location.origin}/`, + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with COOP report-only with coep report-only, + // which mismatches with the current document (opener) COOP (unsafe-none) and + // COOP report-only (same-origin) values. + [ + SAME_ORIGIN, + "", + "", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "require-corp", + [ + { + "endpoint": popupReportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin-plus-coep", + "previousResponseURL": `${location.href}`, + "referrer": `${location.origin}/`, + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html.headers new file mode 100644 index 0000000000..9a8445a43e --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy-Report-Only: same-origin +Referrer-Policy: origin diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-opener.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-opener.https.html new file mode 100644 index 0000000000..893dfa20b8 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-opener.https.html @@ -0,0 +1,67 @@ +<title> + Reports a browsing context group switch when an opener with COOP navigates. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const same_origin = get_host_info().HTTPS_ORIGIN; + +let escapeComma = url => url.replace(/,/g, '\\,'); + +promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. + const opener_token = token(); + const opener_url = same_origin + executor_path + `&uuid=${opener_token}`; + + // The "openee" window. + const openee_token = token(); + const openee_url = same_origin + executor_path + `&uuid=${openee_token}`; + + // The "final" url the opener will navigate to. It has COOP and a reporter. + const final_report_token = reportToken(); + const final_token = token(); + const final_reportTo = reportingEndpointsHeaders(final_report_token); + const final_url = same_origin + executor_path + final_reportTo.header + + final_reportTo.coopSameOriginHeader +`&uuid=${final_token}`; + + // 1. Create the opener window and ensure it doesn't have an opener. + let opener_window_proxy = window.open(opener_url, '_blank', 'noopener'); + t.add_cleanup(() => send(opener_token, "window.close()")); + + // 2. The opener opens a window. + send(opener_token, ` + openee = window.open('${escapeComma(openee_url)}'); + `); + + // 3. Ensure the openee loads. + send(openee_token, ` + send("${this_window_token}", "ACK"); + `); + assert_equals("ACK", await receive(this_window_token)); + + // 4. The opener navigates. + send(opener_token, ` + location.replace('${escapeComma(final_url)}'); + `); + + // 5. Check a report was sent to the opener. + let report = + await receiveReport(final_report_token, "navigation-to-response") + assert_equals(report.type, "coop"); + assert_equals(report.url, final_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "enforce"); + assert_equals(report.body.effectivePolicy, "same-origin"); + assert_equals(report.body.previousResponseURL, opener_url.replace(/"/g, '%22')); +}, "navigation-report-from-opener-navigation"); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html new file mode 100644 index 0000000000..b625b285cf --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html @@ -0,0 +1,85 @@ +<title>Cross-Origin-Opener-Policy: a navigated popup with reporting</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/utils.js"></script> <!-- Use token() to allow running tests in parallel --> +<script src="/common/dispatcher/dispatcher.js"></script> +<script + src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=df3cde15-b00b-4a59-b6e2-498b67a6146e&report_only_id=ebf3a415-7a74-42e1-92d1-e600b1bbe22e"></script> + +<script> + +// This test does the following: +// 1 - This document has COOP: same-origin-allow-popups; report-to="coop-report-endpoint" +// 2 - Open a popup on a same-origin page without COOP, with the coop-popup-report-endpoint +// 3 - Navigate the popup to a same-origin page with COOP, with the coop-redirect-report-endpoint +// it verifies that the reports are properly send for the browsing context switch +// during the navigation in the popup (step 3). The current document (the opener) +// endpoint should not receive any report as no switch ocurred on 2. +promise_test( async t => { + const callbackToken = token(); + const noCoopToken = token(); + const coopToken= token(); + await reportingTest(async resolve => { + const noCOOPUrl = executor_path + + convertToWPTHeaderPipe(getReportingEndpointsHeader(location.origin)) + + `|header(Cross-Origin-Opener-Policy,${encodeURIComponent(`unsafe-none; report-to="${popupReportEndpoint.name}"`)})` + + `&uuid=${noCoopToken}`; + const coopUrl = executor_path + + convertToWPTHeaderPipe(getReportingEndpointsHeader(location.origin)) + + `|header(Cross-Origin-Opener-Policy,${encodeURIComponent(`same-origin; report-to="${redirectReportEndpoint.name}"`)})` + + `&uuid=${coopToken}`; + + // 1. Open a popup without COOP and with reporting. COOP does not trigger + // a browsing context group switch because the current document is + // same-origin-allow-popups + const popup = window.open(noCOOPUrl); + t.add_cleanup(() => send(noCoopToken, "window.close()")); + + // 2. Navigate the popup to a COOP document, which switches the browsing + // context group. + send(noCoopToken, `window.location = "${coopUrl}";`); + t.add_cleanup(() => send(coopToken, "window.close()")); + + // 3. Make sure the new document is loaded. + send(coopToken, ` + send("${callbackToken}", "Ready"); + `); + let reply = await receive(callbackToken); + resolve(); + }, + "", // executor token for the report replacements, unused in this test + [ + // Reports expected for the navigation from "noCOOP" to "coop" + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "unsafe-none", + "nextResponseURL": RegExp(`uuid=${coopToken}$`), + "type": "navigation-from-response" + }, + "url": RegExp(`uuid=${noCoopToken}$`), + "type": "coop" + } + }, + { + "endpoint": redirectReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "previousResponseURL": RegExp(`uuid=${noCoopToken}$`), + "referrer": RegExp(`uuid=${noCoopToken}$`), + "type": "navigation-to-response" + }, + "url": RegExp(`uuid=${coopToken}$`), + "type": "coop" + } + }, + ]); +}, "Open a popup to a document without COOP, then navigate it to a document with"); + +verifyRemainingReports(); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html.sub.headers new file mode 100644 index 0000000000..a6a27c2d3e --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-coop-navigated-popup.https.html.sub.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin-allow-popups; report-to="coop-report-endpoint" +Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=df3cde15-b00b-4a59-b6e2-498b67a6146e", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=ebf3a415-7a74-42e1-92d1-e600b1bbe22e" diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html new file mode 100644 index 0000000000..d674e2e449 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html @@ -0,0 +1,126 @@ +<meta name=timeout content=long> +<title>reporting same origin with report-to</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script +src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=6a739c25-0ec5-4832-b4a3-847281006857&report_only_id=f91209ee-b3a3-474b-b337-d663533745fb"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports + + // Open a same-origin popup with a same-origin COOP and no COEP. Produces two + // reports (one from and one to). Both pages being same origin, the + // next/pervious document urls are available. + [ + SAME_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-allow-popups", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "previousResponseURL": `${location.href}`, // previous documnent url + "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with a same-origin-allow-popup COOP and noCOEP. + // Produces two reports (one from and one to). Both pages being cross origin, + // the next/pervious document urls are not available and the initial document + // url/referrer are used instead. + [ + CROSS_ORIGIN, + `same-origin-allow-popups; report-to="${popupReportEndpoint.name}"`, + "require-corp", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-allow-popups", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-allow-popups", + "previousResponseURL": ``, + "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with a same-origin COOP and COEP, and no reporting. + // Produces one navigation-from-report for this document (the opener). The + // pages being cross origin, the next/pervious document urls are not available + // and the initial document url/referrer are used instead. + [ + CROSS_ORIGIN, + `same-origin`, + "require-corp", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-allow-popups", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // initial navigation URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + } + ] + ], +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html.sub.headers new file mode 100644 index 0000000000..3e213a95a3 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html.sub.headers @@ -0,0 +1,3 @@ +Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=6a739c25-0ec5-4832-b4a3-847281006857", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=f91209ee-b3a3-474b-b337-d663533745fb" +Cross-Origin-Opener-Policy: same-origin-allow-popups; report-to="coop-report-endpoint" +Referrer-Policy: origin diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html new file mode 100644 index 0000000000..88b180702f --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html @@ -0,0 +1,173 @@ +<meta name=timeout content=long> +<title>reporting same origin with report-to</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script + src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=edbbace3-40ca-4640-8d50-dc6e52acc1da&report_only_id=f65cf51a-ca6f-4028-a2c3-0c06183faa13"></script> +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports + + // Open and navigate a popup to a same-origin page with the same COOP-COEP + // settings: no browsing context group switch hence no report expected. + [ + SAME_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "require-corp", + "", + "", + [] + ], + // Open a same-origin popup with a same-origin COOP but no COEP. Produces two + // reports (one from and one to). The from report has an effectivePolicy of + // same-origin-plus-coep, both pages being same origin, the entire + // next/pervious document urls are available. + [ + SAME_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-plus-coep", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next destination url + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "previousResponseURL": `${location.href}`, // previous document url + "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with a same-origin COOP and COEP. Produces two + // reports (one from and one to). The from report has an effectivePolicy of + // same-origin-plus-coep, both pages being cross origin, the next/pervious + // document urls are not available and the initial document url/referrer are + // used instead. + [ + CROSS_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "require-corp", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-plus-coep", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // initial navigation url + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-plus-coep", + "previousResponseURL": ``, + "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a same-origin popup with a same-origin COOP report only. One report + // is sent to this page's endpoint, but none to the report-only endpoint. + [ + SAME_ORIGIN, + "", + "", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "require-corp", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-plus-coep", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // initial navigation url + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with a same-origin COOP report only. A report is + // sent to both this page's endpoint and the popup's. + [ + CROSS_ORIGIN, + "", + "", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "require-corp", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-plus-coep", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // initial navigation url + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportOnlyEndpoint, + "report": { + "body": { + "disposition": "reporting", + "effectivePolicy": "same-origin-plus-coep", + "previousResponseURL": ``, + "referrer": `${location.origin}/`, // referrer (origin, as dictated by the referrer policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html.sub.headers new file mode 100644 index 0000000000..0f78bdb2d0 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-coep-report-to.https.html.sub.headers @@ -0,0 +1,4 @@ +Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=edbbace3-40ca-4640-8d50-dc6e52acc1da", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=f65cf51a-ca6f-4028-a2c3-0c06183faa13" +Cross-Origin-Opener-Policy: same-origin; report-to="coop-report-endpoint" +Cross-Origin-Embedder-Policy: require-corp +Referrer-Policy: origin diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html new file mode 100644 index 0000000000..47bb67cc4b --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html @@ -0,0 +1,216 @@ +<meta name=timeout content=long> +<title>reporting same origin with report-to</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=6aad9729-8642-4894-91d9-a4d44707cd4a&report_only_id=69eb1838-6a03-4cda-97b0-c126ffcb9e8a"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports + + // Open a popup on a same-origin page, with a compatible COOP. + // This is a sanity check that no report are produced. + [ + SAME_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [] + ], + // Open a cross-origin popup with a same-origin COOP. Produces two + // reports (one from and one to). The from report has an effectivePolicy of + // same-origin (corresponding to the current document), both pages being + // cross origin, the next/pervious document urls are not available and the + // initial document url/referrer are used instead. + [ + CROSS_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "previousResponseURL": "", + "referrer": '', // referrer (empty due to the Referrer Policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a same-origin popup with a unsafe-none COOP and no COEP. COOP switches + // the browsing context group and hence produces two reports (one from and one + // to). This test verifies that unsafe-none properly sends report. + [ + SAME_ORIGIN, + `unsafe-none; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "unsafe-none", + "previousResponseURL": `${location.href}`, + "referrer": '', // referrer (empty due to the Referrer Policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a same-origin popup with a same-origin COOP and COEP. The difference + // of COEP values leads to the browsing context group switch and produces two + // reports. This verifies that the navigation-to-document report has an + // effectivePolicy of same-origin-plus-coep. + [ + SAME_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "require-corp", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin-plus-coep", + "previousResponseURL": `${location.href}`, + "referrer": '', // referrer (empty due to the Referrer Policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with no COOP (but reporting) and no COEP. + // Produces two reports. The pages being cross origin, the next/pervious + // document urls are not available and the initial document url/referrer are + // used instead. + [ + CROSS_ORIGIN, + `unsafe-none; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "unsafe-none", + "previousResponseURL": "", + "referrer": '', // referrer (empty due to the Referrer Policy) + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a same-origin popup with no COOP (without reporting) and no COEP. + // Produces one report to this page (opener) endpoint. + // This verifies that the navigated-to-document's COOP report values do not + // impact the navigated-from-document's COOP. + [ + SAME_ORIGIN, + "unsafe-none", + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + } + ] + ] +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.sub.headers new file mode 100644 index 0000000000..79c851a86c --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.sub.headers @@ -0,0 +1,3 @@ +Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=6aad9729-8642-4894-91d9-a4d44707cd4a", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=69eb1838-6a03-4cda-97b0-c126ffcb9e8a" +Cross-Origin-Opener-Policy: same-origin; report-to="coop-report-endpoint" +Referrer-Policy: no-referrer diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html new file mode 100644 index 0000000000..3a8f343f37 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html @@ -0,0 +1,110 @@ +<meta name=timeout content=long> +<title>reporting same origin</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports + + // Open a cross-origin popup with a same-origin COOP and no COEP. COOP + // switches the browsing context group and hence produces one report. + // This test verifies that the navigated to document properly sends a + // navigation-to report. The navigationURI is the referrer. + [ + CROSS_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "previousResponseURL": "", + "referrer": `${location.origin}/`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a same-origin popup with a unsafe-none COOP and no COEP. COOP switches + // the browsing context group and hence produces one report. + // This test verifies that having different policies on same origin documents + // still properly produces report to the navigated-to-document. + [ + SAME_ORIGIN, + `unsafe-none; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "unsafe-none", + "previousResponseURL": `${location.href}`, + "referrer": `${location.href}`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with a unsafe-none COOP (with reporting) and no + // COEP. COOP switches the browsing context group and hence produces one + // reports to the unsafe-none document. This test verifies that unsafe-none + // properly sends report in that configuration. + [ + CROSS_ORIGIN, + `unsafe-none; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "previousResponseURL": "", + "referrer": `${location.origin}/`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a same-origin popup with a same-origin COOP Report only value, the + // report only matches the previous document COOP value, no report is sent. + [ + SAME_ORIGIN, + "", + "", + `same-origin; report-to="${popupReportOnlyEndpoint.name}"`, + "", + [] + ], +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.headers new file mode 100644 index 0000000000..46ad58d83b --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.headers @@ -0,0 +1 @@ +Cross-Origin-Opener-Policy: same-origin diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html new file mode 100644 index 0000000000..2563dbb01f --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html @@ -0,0 +1,126 @@ +<meta name=timeout content=long> +<title>reporting same origin with report-to</title> +<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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/resources/common.js"></script> +<script + src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js?pipe=sub&report_id=1f79b0d5-c2a2-4e0b-8e8c-651af2321964&report_only_id=c50700c8-db1e-4224-b06f-4c6a95a5f4be"></script> + +<script> + +let tests = [ + // popup origin, popup COOP, popup COEP, popup COOP report only, popup COEP report only, expected reports + + // Open a same-origin popup with a same-origin COOP with reporting and no COEP. + // COOP switches the browsing context group and hence produces two reports + // (one from and one to). This test verifies that unsafe-none (from the opener) + // properly sends a report. + [ + SAME_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "unsafe-none", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "previousResponseURL": `${location.href}`, // previous document url + "referrer": `${location.href}`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ], + // Open a same-origin popup with a same-origin COOP (no reporting)and no COEP. + // COOP switches the browsing context group and hence produces one report for + // the navigated from document (this page, the opener). This test differs with + // the previous one as it assert that the navigated to document's COOP reporting + // values do not interfere. + [ + SAME_ORIGIN, + `same-origin`, + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "unsafe-none", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + } + ] + ], + // Open a cross-origin popup with a same-origin COOP and no COEP. COOP switches + // the browsing context group and hence produces two reports. + [ + CROSS_ORIGIN, + `same-origin; report-to="${popupReportEndpoint.name}"`, + "", + "", + "", + [ + { + "endpoint": reportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "unsafe-none", + "nextResponseURL": /uuid=EXECUTOR_UUID$/, // next document URL + "type": "navigation-from-response" + }, + "url": `${location.href}`, + "type": "coop" + } + }, + { + "endpoint": popupReportEndpoint, + "report": { + "body": { + "disposition": "enforce", + "effectivePolicy": "same-origin", + "previousResponseURL": ``, + "referrer": `${location.origin}/`, // referrer + "type": "navigation-to-response" + }, + "url": /uuid=EXECUTOR_UUID$/, + "type": "coop" + } + } + ] + ] +]; + +runNavigationReportingTests(document.title, tests); + +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.sub.headers b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.sub.headers new file mode 100644 index 0000000000..f1f18d6708 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.sub.headers @@ -0,0 +1,2 @@ +Reporting-Endpoints: coop-report-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=1f79b0d5-c2a2-4e0b-8e8c-651af2321964", coop-report-only-endpoint="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=c50700c8-db1e-4224-b06f-4c6a95a5f4be" +Cross-Origin-Opener-Policy: unsafe-none; report-to="coop-report-endpoint" diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html new file mode 100644 index 0000000000..cd2f6b67b3 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-redirect-with-same-origin-allow-popups.https.html @@ -0,0 +1,111 @@ +<title> + Tests the redirect interaction with COOP same-origin-allow-popups. +</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="/common/dispatcher/dispatcher.js"></script> +<script src="/html/cross-origin-opener-policy/reporting/resources/reporting-common.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy"; +const same_origin = { + host: get_host_info().HTTPS_ORIGIN, + name: "Same origin" +}; +const cross_origin = { + host: get_host_info().HTTPS_REMOTE_ORIGIN, + name: "Cross origin" +}; + +// Tests the redirect interaction with COOP same-origin-allow-popups and +// reporting: +// 1 - open the opener document on origin same_origin with COOP +// same-origin-allow-popups. +// 2 - opener opens popup with document on origin popup_origin, no COOP and a +// redirect header (HTTP 302, location). +// 3 - redirection to a document with origin same_origin and COOP +// same-origin-allow-popups. +// +// The navigation (2) to the first document of the popup stays in the same +// browsing context group due to the same-origin-allow-popups COOP of the +// opener. +// The redirect (3) to the final document does since it compares the +// popup_origin/unsafe-none document with the +// same-origin/same-origin-allow-popups document. +// +// A opens B, B redirects to C. +// +// Document Origin COOP +// -------- ------------ ------------------------ +// A same-origin same-origin-allow-popups +// B popup-origin unsafe-none +// C same-origin same-origin-allow-popups +function redirect_test( popup_origin ) { + promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. This has COOP same-origin-allow-popups and a + // reporter. + const opener_report_token = reportToken(); + const opener_token = token(); + const opener_reportTo = reportingEndpointsHeaders(opener_report_token); + const opener_url = same_origin.host + executor_path + + opener_reportTo.header + opener_reportTo.coopSameOriginAllowPopupsHeader + + `&uuid=${opener_token}`; + + // The "openee" window. + // The initial document does not have COOP and is on popup_origin, it + // redirects to a same-origin (with the opener) document with COOP + // same-origin-allow-popups. + const openee_token = token(); + const openee_redirect_url = same_origin.host + executor_path + + opener_reportTo.header + opener_reportTo.coopSameOriginAllowPopupsHeader + + `&uuid=${openee_token}`; + const redirect_header = 'status(302)' + + `|header(Location,${encodeURIComponent( + openee_redirect_url + .replace(/,/g, "\\,") + .replace(/\\\\,/g, "\\\\\\,") + .replace(/\(/g, "%28") + .replace(/\)/g, "%29"))})`; + const openee_url = popup_origin.host + executor_path + redirect_header + + `&uuid=${openee_token}`; + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + t.add_cleanup(() => send(opener_token, "window.close()")); + + // 2. The opener opens its openee. + send(opener_token, ` + openee = window.open("${openee_url}"); + `); + t.add_cleanup(() => send(openee_token, "window.close()")); + + // 3. Check the opener status on the openee. + send(openee_token, ` + send("${this_window_token}", opener !== null); + `); + assert_equals(await receive(this_window_token), "false", "opener"); + + // 4. Check the openee status on the opener. + send(opener_token, ` + send("${this_window_token}", openee.closed); + `); + assert_equals(await receive(this_window_token), "true", "openee.closed"); + + // 5. Check a report sent to the openee. + let report = await receiveReport( + opener_report_token, + "navigation-to-response"); + assert_equals(report.type, "coop"); + assert_equals(report.body.disposition, "enforce"); + assert_equals(report.body.effectivePolicy, "same-origin-allow-popups"); + }, `${popup_origin.name} openee redirected to same-origin with same-origin-allow-popups`); +} + +redirect_test(same_origin); +redirect_test(cross_origin); +</script> diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/reporting-common.js b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/reporting-common.js new file mode 100644 index 0000000000..70bb4897f5 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/reporting-common.js @@ -0,0 +1,422 @@ +const executor_path = "/common/dispatcher/executor.html?pipe="; +const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)'; + +// Report endpoint keys must start with a lower case alphabet character. +// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-header-structure-15#section-4.2.3.3 +const reportToken = () => { + return token().replace(/./, 'a'); +} + +const isWPTSubEnabled = "{{GET[pipe]}}".includes("sub"); + +const getReportEndpointURL = (reportID) => + `/reporting/resources/report.py?reportID=${reportID}`; + +const reportEndpoint = { + name: "coop-report-endpoint", + reportID: isWPTSubEnabled ? "{{GET[report_id]}}" : token(), + reports: [] +}; +const reportOnlyEndpoint = { + name: "coop-report-only-endpoint", + reportID: isWPTSubEnabled ? "{{GET[report_only_id]}}" : token(), + reports: [] +}; +const popupReportEndpoint = { + name: "coop-popup-report-endpoint", + reportID: token(), + reports: [] +}; +const popupReportOnlyEndpoint = { + name: "coop-popup-report-only-endpoint", + reportID: token(), + reports: [] +}; +const redirectReportEndpoint = { + name: "coop-redirect-report-endpoint", + reportID: token(), + reports: [] +}; +const redirectReportOnlyEndpoint = { + name: "coop-redirect-report-only-endpoint", + reportID: token(), + reports: [] +}; + +const reportEndpoints = [ + reportEndpoint, + reportOnlyEndpoint, + popupReportEndpoint, + popupReportOnlyEndpoint, + redirectReportEndpoint, + redirectReportOnlyEndpoint +]; + +// Allows RegExps to be pretty printed when printing unmatched expected reports. +Object.defineProperty(RegExp.prototype, "toJSON", { + value: RegExp.prototype.toString +}); + +function wait(ms) { + return new Promise(resolve => step_timeout(resolve, ms)); +} + +// Check whether a |report| is a "opener breakage" COOP report. +function isCoopOpenerBreakageReport(report) { + if (report.type != "coop") + return false; + + if (report.body.type != "navigation-from-response" && + report.body.type != "navigation-to-response") { + return false; + } + + return true; +} + +async function clearReportsOnServer(host) { + const res = await fetch( + '/reporting/resources/report.py', { + method: "POST", + body: JSON.stringify({ + op: "DELETE", + reportIDs: reportEndpoints.map(endpoint => endpoint.reportID) + }) + }); + assert_equals(res.status, 200, "reports cleared"); +} + +async function pollReports(endpoint) { + const res = await fetch(getReportEndpointURL(endpoint.reportID), + { cache: 'no-store' }); + if (res.status !== 200) { + return; + } + for (const report of await res.json()) { + if (isCoopOpenerBreakageReport(report)) + endpoint.reports.push(report); + } +} + +// Recursively check that all members of expectedReport are present or matched +// in report. +// Report may have members not explicitly expected by expectedReport. +function isObjectAsExpected(report, expectedReport) { + if (( report === undefined || report === null + || expectedReport === undefined || expectedReport === null ) + && report !== expectedReport ) { + return false; + } + if (expectedReport instanceof RegExp && typeof report === "string") { + return expectedReport.test(report); + } + // Perform this check now, as RegExp and strings above have different typeof. + if (typeof report !== typeof expectedReport) + return false; + if (typeof expectedReport === 'object') { + return Object.keys(expectedReport).every(key => { + return isObjectAsExpected(report[key], expectedReport[key]); + }); + } + return report == expectedReport; +} + +async function checkForExpectedReport(expectedReport) { + return new Promise( async (resolve, reject) => { + const polls = 20; + const waitTime = 200; + for (var i=0; i < polls; ++i) { + pollReports(expectedReport.endpoint); + for (var j=0; j<expectedReport.endpoint.reports.length; ++j){ + if (isObjectAsExpected(expectedReport.endpoint.reports[j], + expectedReport.report)){ + expectedReport.endpoint.reports.splice(j,1); + resolve(); + return; + } + }; + await wait(waitTime); + } + reject( + replaceTokensInReceivedReport( + "No report matched the expected report for endpoint: " + + expectedReport.endpoint.name + + ", expected report: " + JSON.stringify(expectedReport.report) + + ", within available reports: " + + JSON.stringify(expectedReport.endpoint.reports) + )); + }); +} + +function replaceFromRegexOrString(str, match, value) { + if (str instanceof RegExp) { + return RegExp(str.source.replace(match, value)); + } + return str.replace(match, value); +} + +// Replace generated values in regexes and strings of an expected report: +// EXECUTOR_UUID: the uuid generated with token(). +function replaceValuesInExpectedReport(expectedReport, executorUuid) { + if (expectedReport.report.body !== undefined) { + if (expectedReport.report.body.nextResponseURL !== undefined) { + expectedReport.report.body.nextResponseURL = replaceFromRegexOrString( + expectedReport.report.body.nextResponseURL, "EXECUTOR_UUID", + executorUuid); + } + if (expectedReport.report.body.previousResponseURL !== undefined) { + expectedReport.report.body.previousResponseURL = replaceFromRegexOrString( + expectedReport.report.body.previousResponseURL, "EXECUTOR_UUID", + executorUuid); + } + if (expectedReport.report.body.referrer !== undefined) { + expectedReport.report.body.referrer = replaceFromRegexOrString( + expectedReport.report.body.referrer, "EXECUTOR_UUID", + executorUuid); + } + } + if (expectedReport.report.url !== undefined) { + expectedReport.report.url = replaceFromRegexOrString( + expectedReport.report.url, "EXECUTOR_UUID", executorUuid); + } + return expectedReport; +} + +function replaceTokensInReceivedReport(str) { + return str.replace(/.{8}-.{4}-.{4}-.{4}-.{12}/g, `(uuid)`); +} + +// Run a test then check that all expected reports are present. +async function reportingTest(testFunction, executorToken, expectedReports) { + await new Promise(testFunction); + expectedReports = Array.from( + expectedReports, + report => replaceValuesInExpectedReport(report, executorToken) ); + await Promise.all(Array.from(expectedReports, checkForExpectedReport)); +} + +function convertToWPTHeaderPipe([name, value]) { + return `header(${name}, ${encodeURIComponent(value)})`; +} + +function getReportToHeader(host) { + return [ + "Report-To", + reportEndpoints.map( + reportEndpoint => { + const reportToJSON = { + 'group': `${reportEndpoint.name}`, + 'max_age': 3600, + 'endpoints': [{ + 'url': `${host}${getReportEndpointURL(reportEndpoint.reportID)}` + }] + }; + // Escape comma as required by wpt pipes. + return JSON.stringify(reportToJSON) + .replace(/,/g, '\\,') + .replace(/\(/g, '\\\(') + .replace(/\)/g, '\\\)='); + } + ).join("\\, ")]; +} + +function getReportingEndpointsHeader(host) { + return [ + "Reporting-Endpoints", + reportEndpoints.map(reportEndpoint => { + return `${reportEndpoint.name}="${host}${getReportEndpointURL(reportEndpoint.reportID)}"`; + }).join("\\, ")]; +} + +// Return Report and Report-Only policy headers. +function getPolicyHeaders(coop, coep, coopRo, coepRo) { + return [ + [`Cross-Origin-Opener-Policy`, coop], + [`Cross-Origin-Embedder-Policy`, coep], + [`Cross-Origin-Opener-Policy-Report-Only`, coopRo], + [`Cross-Origin-Embedder-Policy-Report-Only`, coepRo]]; +} + +function navigationReportingTest(testName, host, coop, coep, coopRo, coepRo, + expectedReports) { + const executorToken = token(); + const callbackToken = token(); + promise_test(async t => { + await reportingTest(async resolve => { + const openee_headers = [ + getReportingEndpointsHeader(host.origin), + ...getPolicyHeaders(coop, coep, coopRo, coepRo) + ].map(convertToWPTHeaderPipe); + const openee_url = host.origin + executor_path + + openee_headers.join('|') + `&uuid=${executorToken}`; + const openee = window.open(openee_url); + const uuid = token(); + t.add_cleanup(() => send(uuid, "window.close()")); + + // 1. Make sure the new document is loaded. + send(executorToken, ` + send("${callbackToken}", "Ready"); + `); + let reply = await receive(callbackToken); + assert_equals(reply, "Ready"); + resolve(); + }, executorToken, expectedReports); + }, `coop reporting test ${testName} to ${host.name} with ${coop}, ${coep}, ${coopRo}, ${coepRo}`); +} + +function navigationDocumentReportingTest(testName, host, coop, coep, coopRo, + coepRo, expectedReports) { + const executorToken = token(); + const callbackToken = token(); + promise_test(async t => { + const openee_headers = [ + getReportingEndpointsHeader(host.origin), + ...getPolicyHeaders(coop, coep, coopRo, coepRo) + ].map(convertToWPTHeaderPipe); + const openee_url = host.origin + executor_path + + openee_headers.join('|') + `&uuid=${executorToken}`; + window.open(openee_url); + t.add_cleanup(() => send(executorToken, "window.close()")); + // Have openee window send a message through dispatcher, once we receive + // the Ready message from dispatcher it means the openee is fully loaded. + send(executorToken, ` + send("${callbackToken}", "Ready"); + `); + let reply = await receive(callbackToken); + assert_equals(reply, "Ready"); + + await wait(1000); + + expectedReports = expectedReports.map( + (report) => replaceValuesInExpectedReport(report, executorToken)); + return Promise.all(expectedReports.map( + async ({ endpoint, report: expectedReport }) => { + await pollReports(endpoint); + for (let report of endpoint.reports) { + assert_true(isObjectAsExpected(report, expectedReport), + `report received for endpoint: ${endpoint.name} ${JSON.stringify(report)} should match ${JSON.stringify(expectedReport)}`); + } + assert_equals(endpoint.reports.length, 1, `has exactly one report for ${endpoint.name}`) + })); + }, `coop document reporting test ${testName} to ${host.name} with ${coop}, ${coep}, ${coopRo}, ${coepRo}`); +} + +// Run an array of reporting tests then verify there's no reports that were not +// expected. +// Tests' elements contain: host, coop, coep, coop-report-only, +// coep-report-only, expectedReports. +// See isObjectAsExpected for explanations regarding the matching behavior. +async function runNavigationReportingTests(testName, tests) { + await clearReportsOnServer(); + tests.forEach(test => { + navigationReportingTest(testName, ...test); + }); + verifyRemainingReports(); +} + +// Run an array of reporting tests using Reporting-Endpoints header then +// verify there's no reports that were not expected. +// Tests' elements contain: host, coop, coep, coop-report-only, +// coep-report-only, expectedReports. +// See isObjectAsExpected for explanations regarding the matching behavior. +function runNavigationDocumentReportingTests(testName, tests) { + clearReportsOnServer(); + tests.forEach(test => { + navigationDocumentReportingTest(testName, ...test); + }); +} + +function verifyRemainingReports() { + promise_test(t => { + return Promise.all(reportEndpoints.map(async (endpoint) => { + await pollReports(endpoint); + assert_equals(endpoint.reports.length, 0, `${endpoint.name} should be empty`); + })); + }, "verify remaining reports"); +} + +const receiveReport = async function(uuid, type) { + while(true) { + let reports = await Promise.race([ + receive(uuid), + new Promise(resolve => { + step_timeout(resolve, 1000, "timeout"); + }) + ]); + if (reports == "timeout") + return "timeout"; + reports = JSON.parse(reports); + for(report of reports) { + if (report?.body?.type == type) + return report; + } + } +} + +const coopHeaders = function (uuid) { + // Use a custom function instead of convertToWPTHeaderPipe(), to avoid + // encoding double quotes as %22, which messes with the reporting endpoint + // registration. + let getHeader = (uuid, coop_value, is_report_only) => { + const header_name = + is_report_only ? + "Cross-Origin-Opener-Policy-Report-Only": + "Cross-Origin-Opener-Policy"; + return `|header(${header_name},${coop_value}%3Breport-to="${uuid}")`; + } + + return { + coopSameOriginHeader: + getHeader(uuid, "same-origin", is_report_only = false), + coopSameOriginAllowPopupsHeader: + getHeader(uuid, "same-origin-allow-popups", is_report_only = false), + coopRestrictPropertiesHeader: + getHeader(uuid, "restrict-properties", is_report_only = false), + coopReportOnlySameOriginHeader: + getHeader(uuid, "same-origin", is_report_only = true), + coopReportOnlySameOriginAllowPopupsHeader: + getHeader(uuid, "same-origin-allow-popups", is_report_only = true), + coopReportOnlyRestrictPropertiesHeader: + getHeader(uuid, "restrict-properties", is_report_only = true), + }; +} + +// 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})`, + ...coopHeaders(uuid) + }; +}; + +// Build a set of headers to tests the reporting API. This defines a set of +// matching 'Reporting-Endpoints', 'Cross-Origin-Opener-Policy' and +// 'Cross-Origin-Opener-Policy-Report-Only' headers. +const reportingEndpointsHeaders = function (uuid) { + // Report endpoint keys must start with a lower case alphabet: + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-header-structure-15#section-4.2.3.3 + assert_true(uuid.match(/^[a-z].*/) != null, 'Use reportToken() instead.'); + + const report_endpoint_url = dispatcher_path + `?uuid=${uuid}`; + const reporting_endpoints_header = `${uuid}="${report_endpoint_url}"`; + + return { + header: `|header(Reporting-Endpoints,${reporting_endpoints_header})`, + ...coopHeaders(uuid) + }; +}; diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/test-access-property.js b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/test-access-property.js new file mode 100644 index 0000000000..a405202431 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/test-access-property.js @@ -0,0 +1,65 @@ +const same_origin = get_host_info().HTTPS_ORIGIN; +const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; + +const origin = [ + ["same-origin" , same_origin ], + ["cross-origin", cross_origin], +]; +let escapeComma = url => url.replace(/,/g, '\\,'); + +let testAccessProperty = ( + property, + op, + expectReport = true, + use_restrict_properties = false, +) => { + origin.forEach(([origin_name, origin]) => { + promise_test(async t => { + const this_window_token = token(); + + // The opener window: + const opener_token = token(); + const opener_url = get_host_info().HTTP_ORIGIN + executor_path + + `&uuid=${opener_token}`; + + // The openee window: + const openee_token = token(); + const openee_report_token = token(); + const openee_report_to = reportToHeaders(openee_report_token); + const coop_ro_header = + use_restrict_properties + ? openee_report_to.coopReportOnlyRestrictPropertiesHeader + : openee_report_to.coopReportOnlySameOriginHeader; + const openee_url = origin + executor_path + openee_report_to.header + + coop_ro_header + coep_header + `&uuid=${openee_token}`; + + t.add_cleanup(() => { + send(opener_token, "window.close()") + send(openee_token, "window.close()") + }); + + // Open the two windows. Wait for them to be loaded. + window.open(opener_url); + send(opener_token, ` + window.openee = window.open('${escapeComma(openee_url)}'); + `); + send(openee_token, `send("${this_window_token}", "Ready");`); + assert_equals(await receive(this_window_token), "Ready"); + + // 2. Try to access the openee. + send(opener_token, `(${op})(openee);`); + + // 3. Fetch reports sent to the openee. + let report = await receiveReport(openee_report_token, + "access-to-coop-page-from-opener"); + if (expectReport) { + assert_equals(report.body.property, property); + } else { + // "timeout" should be returned if no such reports are received. + assert_equals(report, "timeout"); + } + + + }, `${origin_name} > ${op}`); + }) +}; diff --git a/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/try-access.js b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/try-access.js new file mode 100644 index 0000000000..a06cb07904 --- /dev/null +++ b/testing/web-platform/tests/html/cross-origin-opener-policy/reporting/resources/try-access.js @@ -0,0 +1,20 @@ +// A function trying to access to |w| through a "CrossOrigin" attribute (blur). +// This function is kept in its own file to ensure the source location of the +// call stays constant. +function tryAccess(w) { + try { + w.blur(); + } catch(e) {} +} + +function assert_source_location_found(report) { + assert_true(report.body.sourceFile.includes("try-access.js")); + assert_equals(report.body.lineNumber, 6); + assert_equals(report.body.columnNumber, 7); +} + +function assert_source_location_missing(report) { + assert_equals(report.body.sourceFile, undefined); + assert_equals(report.body.lineNumber, undefined); + assert_equals(report.body.columnNumber, undefined); +} |