Skip to content

Commit

Permalink
Add wpt tests for Document-Reporting Endpoints header
Browse files Browse the repository at this point in the history
- These tests describe the desired behaviour according to the spec
- This includes the following cases:
  1) Sending reports to default endpoint
  2) Setting Reporting-Endpoints header with path-absolute url
  3) Sending reports to multiple named endpoints
  4) Endpoint with the same name gets overridden
  5) Document has both Report-To and Reporting-Endpoints header
  6) Reports are not batched for same endpoint, same url in two frame
  7) Reports are not sent after navigating from document with
     Reporting-Endpoints header to same url without header
- Update uuid used in various Reporting-Endpoints header's reportID so
  they're actually unique among tests.

Bug: 1062359
Change-Id: I42f268e8421407d3f9b745b7d762c4775f247500
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3060743
Commit-Queue: Rodney Ding <[email protected]>
Reviewed-by: Ian Clelland <[email protected]>
Cr-Commit-Position: refs/heads/main@{#924487}
NOKEYCHECK=True
GitOrigin-RevId: b44ebf9ab3c73ffd63d81305bba140be0981c59c
  • Loading branch information
r0dneyP3 authored and copybara-github committed Sep 23, 2021
1 parent 4dcfc0f commit 3c46e54
Show file tree
Hide file tree
Showing 25 changed files with 353 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
reportCountReport.onload = reportCountTest.step_func(function () {
var data = JSON.parse(reportCountReport.responseText);

assert_equals(data.report_count, reportCount, "Report count was not what was expected.");
assert_equals(data.report_count, +reportCount, "Report count was not what was expected.");

reportCountTest.done();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const id = 'd0d517bf-891b-457a-b970-8b2b2c81a0bf';
const id = 'fe5ca189-269a-4e74-a4dd-d7a3b33139d5';

promise_test(async t => {
// Set credentials, and set up test to clear them afterwards.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Reporting-Endpoints: csp-endpoint="https://{{domains[www1]}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf"
Reporting-Endpoints: csp-endpoint="https://{{domains[www1]}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=fe5ca189-269a-4e74-a4dd-d7a3b33139d5"
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-endpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>

<head>
<title>Test that reports ignore Report-To header when Reporting-Endpoints is configured</title>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='resources/report-helper.js'></script>
</head>

<body>
<script>
promise_test(async t => {
return new Promise(resolve => {
new ReportingObserver((reports, observer) => resolve(reports),
{ types: ['document-policy-violation'] }).observe();
}).then((reports) => {
assert_equals(reports[0].type, 'document-policy-violation');
})
}, "document policy violation observed");
</script>
<script>document.write("This should be written into the document");</script>
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const report_to_id = 'caddb022-90ea-48e8-a675-4cebaf7e8388';
const reporting_endpoints_id = '6c2131d0-1e9b-4ee8-a196-952f2ae4ae97';
promise_test(async t => {
await wait(3000);
// Verify no reports sent to Report-To endpoint
let reports = await pollReports(endpoint, report_to_id);
assert_equals(reports.length, 0);
// Verify report is received on Reporting-Endpoints endpoint
reports = await pollReports(endpoint, reporting_endpoints_id);
checkReportExists(reports, 'document-policy-violation', location.href);
}, "Only the Reporting-Endpoints configured endpoint received reports.");
</script>

</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Reporting-Endpoints: group1="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=6c2131d0-1e9b-4ee8-a196-952f2ae4ae97"
Report-To: { "group": "group1", "max_age": 10886400, "endpoints": [{ "url": "/reporting/resources/report.py?reportID=caddb022-90ea-48e8-a675-4cebaf7e8388" }] }
Document-Policy-Report-Only: document-write=?0;report-to=group1
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<meta charset=utf-8>
<title>Test that document level reports are sent to default endpoint</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src='resources/report-helper.js'></script>
<p id="error">No error</p>
<script>
async_test(function (test) {
var observer = new ReportingObserver(function (reports) {
test.step(function () {
assert_equals(reports.length, 1);
assert_equals(reports[0].type, "deprecation");
});
test.done();
});
observer.observe();
}, "report generated");
</script>
<script>window.webkitStorageInfo;</script>
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const id = '46ecac28-6d27-4763-a692-bcc588054716';
promise_test(async t => {
await wait(3000);
const reports = await pollReports(endpoint, id);
checkReportExists(reports, 'deprecation', location.href);
}, "Reporting-Endpoints defined endpoint received reports.");
</script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reporting-Endpoints: default="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=46ecac28-6d27-4763-a692-bcc588054716"
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>

<head>
<title>Test that reports are not sent without Reporting-Endpoints header, with previous header set on same URL</title>
<script src="/common/utils.js"></script>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='resources/report-helper.js'></script>
</head>

<body>
<iframe name="test"></iframe>
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const report_id = token();
const document_url =
`resources/generate-report-once.py?reportID=${report_id}`;
promise_test(async t => {
// Load a document that generates report into iframe. Server should return
// Reporting-Endpoints header.
const w = window.open(document_url, "test");
await wait(1000);
let reports = await pollReports(endpoint, report_id);
// Verify that reporting is configured on the document.
assert_equals(reports.length, 1);
// reload opened window. This time server will not return
// Reporting-Endpoints header.
w.location.reload();
await wait(1000);
reports = await pollReports(endpoint, report_id);
// Verify no reports are sent this time.
assert_equals(reports.length, 0);

}, "No more reports received after navigation to same document without endpoint header");
</script>

</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<html>

<head>
<title>Test that reports are sent to multiple named endpoints</title>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='resources/report-helper.js'></script>
</head>

<body>
<script>
const t = async_test("Test that image does not load");
async_test(function (t) {
const observer = new ReportingObserver((reports, observer) => {
t.step(() => {
assert_equals(reports[0].type, 'csp-violation');
});
t.done();
}, { types: ['csp-violation'] });
observer.observe();
}, "csp violation report observed");

promise_test(async t => {
return new Promise(resolve => {
new ReportingObserver((reports, observer) => resolve(reports),
{ types: ['document-policy-violation'] }).observe();
}).then((reports) => {
assert_equals(reports[0].type, 'document-policy-violation');
})
}, "document policy violation observed");
</script>
<img src='/reporting/resources/fail.png' onload='t.unreached_func("The image should not have loaded");'
onerror='t.done();'>
<script>document.write("This should be written into the document");</script>
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const group1_id = '0d334af1-1c5c-4e59-9079-065131ff2a45';
const group2_id = '09c1a265-5fc7-4c49-b35c-32078c2d0c19';
promise_test(async t => {
await wait(3000);
// Verify CSP reports are sent to configured endpoint.
const csp_reports = await pollReports(endpoint, group1_id);
checkReportExists(csp_reports, 'csp-violation', location.href);
// Verify Document Policy reports are sent to configured endpoint.
const dp_reports = await pollReports(endpoint, group2_id);
checkReportExists(dp_reports, 'document-policy-violation', location.href);
}, "Reporting endpoints received reports.");
</script>

</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Reporting-Endpoints: group1="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=0d334af1-1c5c-4e59-9079-065131ff2a45"
Reporting-Endpoints: group2="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=09c1a265-5fc7-4c49-b35c-32078c2d0c19"
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to group1
Document-Policy-Report-Only: document-write=?0;report-to=group2
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>

<head>
<title>Test that reports are sent to multiple named endpoints</title>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='resources/report-helper.js'></script>
</head>

<body>
<iframe name="report1"></iframe>
<iframe name="report2"></iframe>
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const report_id = '204d2fb2-018b-4e35-964c-5e298e89d4e2';
promise_test(async t => {
const w = window.open(`resources/generate-report.https.sub.html?pipe=header(Reporting-Endpoints,default="/reporting/resources/report.py?reportID=${report_id}")`, "report1");
const w2 = window.open(`resources/generate-csp-report.https.sub.html?pipe=header(Reporting-Endpoints,default="/reporting/resources/report.py?reportID=${report_id}")`, "report2");
await wait(3000);
// Verify that each iframe generated and sent one report.
const reports = await pollReports(endpoint, report_id);
assert_equals(reports.length, 2, "Number of reports");
checkReportExists(reports, 'deprecation', w.location.href);
checkReportExists(reports, 'csp-violation', w2.location.href);
const request_count = await pollNumResults(endpoint, report_id);
// Verify that requests are sent separately.
assert_equals(request_count, 2, "Count of requests");
}, "Reports are not batched for same url in different document.");
</script>

</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>

<head>
<title>Test that Reporting-Endpoints header endpoint with same name override previous value</title>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='resources/report-helper.js'></script>
</head>

<body>
<script>
promise_test(async t => {
return new Promise(resolve => {
new ReportingObserver((reports, observer) => resolve(reports),
{ types: ['document-policy-violation'] }).observe();
}).then((reports) => {
assert_equals(reports[0].type, 'document-policy-violation');
})
}, "document policy violation observed");
</script>
<script>document.write("This should be written into the document");</script>
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const first_group1_id = 'b523d7f5-28f0-4be6-9460-e163ee9b4ab8';
const second_group1_id = '03e4474d-768c-42f2-8e17-39aa95b309e3';
promise_test(async t => {
await wait(3000);
// Verify that no reports are sent to old header endpoint.
let reports = await pollReports(endpoint, first_group1_id);
assert_equals(reports.length, 0);
// Verify that reports are sent to the new header endpoint.
reports = await pollReports(endpoint, second_group1_id);
checkReportExists(reports, 'document-policy-violation', location.href);
}, "Only the second reporting endpoint received reports.");
</script>

</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Reporting-Endpoints: group1="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=b523d7f5-28f0-4be6-9460-e163ee9b4ab8"
Reporting-Endpoints: group1="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=03e4474d-768c-42f2-8e17-39aa95b309e3"
Document-Policy-Report-Only: document-write=?0;report-to=group1
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<meta charset=utf-8>
<title>Test that Reporting-Endpoints report received for absolute path endpoint.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src='resources/report-helper.js'></script>
<p id="error">No error</p>
<script>
async_test(function (test) {
var observer = new ReportingObserver(function (reports) {
test.step(function () {
// Reports should be received in the same order that they were
// generated.
assert_equals(reports.length, 1);
assert_equals(reports[0].type, "deprecation");
});
test.done();
});
observer.observe();
}, "report generated");
</script>
<script>window.webkitStorageInfo;</script>
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const id = '8106c1d6-55f7-4c82-a8e1-fabc59f890f8';
promise_test(async t => {
await wait(3000);
const reports = await pollReports(endpoint, id);
checkReportExists(reports, 'deprecation', location.href);
}, "Reporting-Endpoints defined endpoint received reports.");
</script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reporting-Endpoints: default="/reporting/resources/report.py?reportID=8106c1d6-55f7-4c82-a8e1-fabc59f890f8"
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<script>
promise_test(async t => {
const endpoint = `${base_url}/reporting/resources/report.py`;
const id = 'd0d517bf-891b-457a-b970-8b2b2c81a0bf';
const id = '33444bb6-e444-4978-9d62-d3825844041f';
await wait(3000);
const reports = await pollReports(endpoint, id);
checkReportExists(reports, 'csp-violation', location.href);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Report-To: { "group": "csp-group", "max_age": 10886400, "endpoints": [{ "url": "/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf" }] }
Report-To: { "group": "csp-group", "max_age": 10886400, "endpoints": [{ "url": "/reporting/resources/report.py?reportID=33444bb6-e444-4978-9d62-d3825844041f" }] }
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-group
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Generate CSP reports </title>
<img src='/reporting/resources/fail.png'>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to default
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
def main(request, response):
# Handle CORS preflight requests
if request.method == u'OPTIONS':
# Always reject preflights for one subdomain
if b"www2" in request.headers[b"Origin"]:
return (400, [], u"CORS preflight rejected for www2")
return [
(b"Content-Type", b"text/plain"),
(b"Access-Control-Allow-Origin", b"*"),
(b"Access-Control-Allow-Methods", b"get"),
(b"Access-Control-Allow-Headers", b"Content-Type"),
], u"CORS allowed"

if b"reportID" in request.GET:
key = request.GET.first(b"reportID")
else:
response.status = 400
return "reportID parameter is required."

with request.server.stash.lock:
visited = request.server.stash.take(key=key)
if visited is None:
response.headers.set("Reporting-Endpoints",
b"default=\"/reporting/resources/report.py?reportID=%s\"" % key)
request.server.stash.put(key=key, value=True)

response.content = b"""
<!DOCTYPE HTML>
<meta charset=utf-8>
<title>Generate deprecation report</title>
<script>
window.webkitStorageInfo;
</script>
"""
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!DOCTYPE HTML>
<meta charset=utf-8>
<title>Generate deprecation report</title>
<script>
window.webkitStorageInfo;
</script>
Loading

0 comments on commit 3c46e54

Please sign in to comment.