Skip to content

Commit

Permalink
Add new tests for credentials and isolation in reporting.
Browse files Browse the repository at this point in the history
This adds WPT to ensure that credentials are not sent to cross-origin
reporting endpoints, that they *are* sent to same-origin reporting
endpoints (currently failing; tracked as crbug.com/1163645), and that
reports which come from documents with different origins are not sent
in the same bundle, even when configured to deliver reports to the same
endpoint.

Change-Id: Icb36647d02ad33e8a2f10901782ad9b92cd0f191
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2657296
Commit-Queue: Ian Clelland <iclelland@chromium.org>
Reviewed-by: Rodney Ding <rodneyding@google.com>
Cr-Commit-Position: refs/heads/main@{#920222}
NOKEYCHECK=True
GitOrigin-RevId: 1301ef614054581a025c24336e15072f0613c21a
  • Loading branch information
clelland authored and copybara-github committed Sep 10, 2021
1 parent a42624c commit ba19044
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 4 deletions.
4 changes: 3 additions & 1 deletion blink/web_tests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -6850,9 +6850,11 @@ crbug.com/1110752 http/tests/devtools/application-panel/resources-panel-resource
crbug.com/1110752 http/tests/devtools/application-panel/resources-panel-selection-on-reload.js [ Pass Failure ]
crbug.com/1110752 http/tests/devtools/application-panel/resources-panel-websql.js [ Pass Failure ]

# Credentials in same-origin Reporting-API reports are currently not implemented.
crbug.com/1163645 external/wpt/reporting/same-origin-report-credentials.https.sub.html [ Failure ]

# Sheriff 2021-09-08
crbug.com/1233826 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/valid-image-before-load.https.html [ Crash Pass Failure ]
crbug.com/1233826 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/valid-image-after-load.https.html [ Crash Pass Failure ]
crbug.com/1247758 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-composite-shadow-part4.html [ Pass Crash ]
crbug.com/1247758 [ Mac ] virtual/oopr-canvas2d/fast/canvas/canvas-blending-color-over-pattern.html [ Pass Crash ]

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test that reports are sent without credentials to cross-origin 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 base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const id = 'd0d517bf-891b-457a-b970-8b2b2c81a0bf';

promise_test(async t => {
// Set credentials, and set up test to clear them afterwards.
await fetch('/cookies/resources/set-cookie.py?name=report&path=%2F', {mode: 'no-cors', credentials: 'include', cache: 'no-store'});
t.add_cleanup(() => fetch("/cookies/resources/set.py?report=; path=%2F; expires=Thu, 01 Jan 1970 00:00:01 GMT"));

// Trigger a CSP error.
await new Promise(resolve => {
const img = document.createElement('img');
img.src = "/reporting/resources/fail.png";
img.addEventListener('error', resolve);
document.body.appendChild(img);
});

// Wait for report to be received.
await wait(3000);
const reports = await pollReports(endpoint, id);
checkReportExists(reports, 'csp-violation', location.href);

// Validate that credentials were not sent to cross-origin endpoint.
const cookies = await pollCookies(endpoint, id);
assert_equals(Object.keys(cookies).length, 0, "Credentials were absent from report");
}, "Reporting endpoints did not receive credentials.");
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Reporting-Endpoints: csp-endpoint="https://{{domains[www1]}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf"
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,46 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test that reports from different origins are not sent together</title>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='resources/report-helper.js'></script>
</head>
<body>
<script>
const base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const id = 'd0d517bf-891b-457a-b970-8b2b2c81a0bf';

promise_test(async t => {

// Attach a cross-origin iframe which should post back here immediately
// before generating a CSP error. That error should be reported to the
// same endpoint that this frame reports to.
await new Promise(resolve => {
const iframe = document.createElement('iframe');
iframe.src = "https://{{domains[www]}}:{{ports[https][0]}}/reporting/resources/csp-error.https.sub.html";
addEventListener('message', resolve);
document.body.appendChild(iframe);
});

// Trigger a CSP error and report in this frame as well.
await new Promise(resolve => {
const img = document.createElement('img');
img.src = "/reporting/resources/fail.png";
img.addEventListener('error', resolve);
document.body.appendChild(img);
});

// Wait for 2 reports to be received.
await wait(3000);
const reports = await pollReports(endpoint, id, 2);
assert_equals(reports.length, 2);

// Validate that reports were sent in separate requests.
const request_count = await pollNumResults(endpoint, id);
assert_equals(request_count, 2);
}, "Reports were sent in two requests.");
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Reporting-Endpoints: csp-endpoint="https://{{domains[www]}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf"
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,19 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Notify parent on load and generate a CSP error</title>
</head>
<body>
<script>
addEventListener('load', () => {
// Alert the parent frame that this frame has loaded.
parent.postMessage('Loaded','*');

// Trigger a CSP error, which should generate a report.
const img = document.createElement('img');
img.src = "/reporting/resources/fail.png";
document.body.appendChild(img);
});
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Reporting-Endpoints: csp-endpoint="https://{{domains[www]}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf"
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-endpoint
22 changes: 19 additions & 3 deletions blink/web_tests/external/wpt/reporting/resources/report-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ function wait(ms) {
return new Promise(resolve => step_timeout(resolve, ms));
}

async function pollReports(endpoint, id) {
const res = await fetch(`${endpoint}?reportID=${id}`, {cache: 'no-store'});
async function pollReports(endpoint, id, min_count) {
const res = await fetch(`${endpoint}?reportID=${id}${min_count ? `&min_count=${min_count}` : ''}`, {cache: 'no-store'});
const reports = [];
if (res.status === 200) {
for (const report of await res.json()) {
Expand All @@ -13,10 +13,26 @@ async function pollReports(endpoint, id) {
return reports;
}

async function pollCookies(endpoint, id) {
const res = await fetch(`${endpoint}?reportID=${id}&op=retrieve_cookies`, {cache: 'no-store'});
const dict = await res.json();
if (dict.reportCookies == 'None')
return {};
return dict.reportCookies;
}

async function pollNumResults(endpoint, id) {
const res = await fetch(`${endpoint}?reportID=${id}&op=retrieve_count`, {cache: 'no-store'});
const dict = await res.json();
if (dict.report_count == 'None')
return 0;
return JSON.parse(dict.report_count);
}

function checkReportExists(reports, type, url) {
for (const report of reports) {
if (report.type !== type) continue;
if (report.body.sourceFile === url) return true;
if (report.body.documentURL == url || report.body.sourceFile === url) return true;
}
assert_unreached(`A report of ${type} from ${url} is not found.`);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test that reports are sent with credentials to same-origin 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 base_url = `${location.protocol}//${location.host}`;
const endpoint = `${base_url}/reporting/resources/report.py`;
const id = 'd0d517bf-891b-457a-b970-8b2b2c81a0bf';

promise_test(async t => {
// Set credentials, and set up test to clear them afterwards.
await fetch('/cookies/resources/set-cookie.py?name=report&path=%2F', {mode: 'no-cors', credentials: 'include', cache: 'no-store'});
t.add_cleanup(() => fetch("/cookies/resources/set.py?report=; path=%2F; expires=Thu, 01 Jan 1970 00:00:01 GMT"));

// Trigger a CSP error.
await new Promise(resolve => {
const img = document.createElement('img');
img.src = "/reporting/resources/fail.png";
img.addEventListener('error', resolve);
document.body.appendChild(img);
});

// Wait for report to be received.
await wait(3000);
const reports = await pollReports(endpoint, id);
checkReportExists(reports, 'csp-violation', location.href);

// Validate that credentials were sent to same-origin endpoint.
const cookies = await pollCookies(endpoint, id);
assert_true('report' in cookies, "Credentials were present in report");
assert_equals(cookies.report, "[report=1]", "Credential value was correct");
}, "Reporting endpoints received credentials.");
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf"
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-endpoint

0 comments on commit ba19044

Please sign in to comment.