Commit 4e32eae7 authored by arthursonzogni's avatar arthursonzogni Committed by Commit Bot

[COOP] Access reporting: More tests for indexed/named getters.

Expand the WPT tests:
 - property.https.html
Into:
 - property.https.html
 - property-indexed-getter.https.html
 - property-named-getter.https.html

This adds more test cases for accesses made using the indexed/named getter.

This is subject to change, but the future implementations of COOP access
reporting for the CrossOrigin named/indexed getter might have some
limitations. The new tests were made to reflect this.

We might catch only the accesses that would have returned an
iframe. This is mainly caused by addressing this suggestion:
https://chromium-review.googlesource.com/c/chromium/src/+/2339353/1/third_party/blink/renderer/bindings/templates/interface.cc.tmpl

The call to ReportCoopAccess is likely going to be made from:
V8Window::NamedPropertyGetterCustom(..)
which is called by:
-> V8Window::CrossOriginNamedGetter(..)
-> V8Window::NamedPropertyGetterCallback

This function is called numerous time, not only for the CrossOrigin method, but for almost all accesses.
For now, the scope of COOP access reporting is limited to the "CrossOrigin"
attribute/methods from the Window.idl file.

This function is trying match the "name" with:
 1. A CrossOrigin attribute/operations.
 2. A named iframe.
 3. A cross-origin interceptor.
 4. An element with a matching name or ID in the document.
 5. Abort and fallback to checking the context (unsure).

Even if we don't catch all accesses, we must at least catch (2) and likely (4).

Bug: 1090273
Change-Id: Id2b115dab83f0e53b4ab459dbb1f500d64d59956
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2346247Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796794}
parent f1bbf557
This is a testharness.js-based test.
FAIL cross-origin > w => w[0] assert_equals: expected 1 but got 0
PASS cross-origin > w => w[1]
PASS cross-origin > w => w[-1]
FAIL same-site > w => w[0] assert_equals: expected 1 but got 0
PASS same-site > w => w[1]
PASS same-site > w => w[-1]
Harness: the test ran to completion.
<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="../resources/dispatcher.js"></script>
<script>
const directory = "/html/cross-origin-opener-policy/reporting";
const executor_path = directory + "/resources/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>
This is a testharness.js-based test.
FAIL same-site > w => w["iframeName"] assert_equals: expected 1 but got 0
FAIL cross-origin > w => w["iframeName"] assert_equals: expected 1 but got 0
FAIL same-site > w => w["divID"] assert_equals: expected 1 but got 0
PASS cross-origin > w => w["divID"]
PASS same-site > w => w["existingGlobal"]
PASS cross-origin > w => w["existingGlobal"]
PASS same-site > w => w["missingGlobal"]
PASS cross-origin > w => w["missingGlobal"]
Harness: the test ran to completion.
<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="../resources/dispatcher.js"></script>
<script>
const directory = "/html/cross-origin-opener-policy/reporting";
const executor_path = directory + "/resources/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>
......@@ -4,11 +4,9 @@ PASS cross-origin > w => w.close()
PASS cross-origin > w => w.closed
PASS cross-origin > w => w.focus()
PASS cross-origin > w => w.frames
FAIL cross-origin > w => w[0] assert_not_equals: Report not received got disallowed value "timeout"
PASS cross-origin > w => w.length
PASS cross-origin > w => w.location
PASS cross-origin > w => w.location = "#"
FAIL cross-origin > w => w["test"] assert_not_equals: Report not received got disallowed value "timeout"
PASS cross-origin > w => w.opener
FAIL cross-origin > w => w.opener = "" assert_not_equals: Report not received got disallowed value "timeout"
PASS cross-origin > w => w.postMessage("")
......@@ -21,11 +19,9 @@ PASS same-site > w => w.close()
PASS same-site > w => w.closed
PASS same-site > w => w.focus()
PASS same-site > w => w.frames
FAIL same-site > w => w[0] assert_not_equals: Report not received got disallowed value "timeout"
PASS same-site > w => w.length
PASS same-site > w => w.location
PASS same-site > w => w.location = "#"
FAIL same-site > w => w["test"] assert_not_equals: Report not received got disallowed value "timeout"
PASS same-site > w => w.opener
PASS same-site > w => w.opener = ""
PASS same-site > w => w.postMessage("")
......
......@@ -22,11 +22,9 @@ let property= [
["closed" , w => w.closed ] ,
["focus" , w => w.focus() ] ,
["frames" , w => w.frames ] ,
["indexed" , w => w[0] ] ,
["length" , w => w.length ] ,
["location" , w => w.location ] ,
["location" , w => w.location = "#" ] ,
["named" , w => w["test"] ] ,
["opener" , w => w.opener ] ,
["opener" , w => w.opener = "" ] ,
["postMessage" , w => w.postMessage("") ] ,
......@@ -44,8 +42,8 @@ origin.forEach(([origin_name, origin]) => {
const opener_token = token(); // The current test window.
const reportTo = reportToHeaders(report_token);
const openee_url = origin+ executor_path +
reportTo.header + reportTo.coopReportOnlySameOriginHeader + coep_header +
const openee_url = origin + executor_path + reportTo.header +
reportTo.coopReportOnlySameOriginHeader + coep_header +
`&uuid=${openee_token}`;
const openee = window.open(openee_url);
t.add_cleanup(() => send(openee_token, "window.close()"))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment