blob: 37cc4ea30e8c18fa641bdbe338d0f38619708dc3 [file] [log] [blame] [edit]
<!DOCTYPE html>
<title>CSP for subresource WebBundle (blocked cases)</title>
<link
rel="help"
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
/>
<meta
http-equiv="Content-Security-Policy"
content="
script-src
urn:
https://web-platform.test:8444/resources/testharness.js
https://web-platform.test:8444/resources/testharnessreport.js
'unsafe-inline';
img-src
https://web-platform.test:8444/web-bundle/resources/wbn/subresource.wbn;
frame-src
urn:;
report-to
csp-group"
>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<link rel="webbundle" href="../resources/wbn/subresource.wbn"
resources="https://web-platform.test:8444/web-bundle/resources/wbn/fail.png" />
<link rel="webbundle" href="../resources/wbn/urn-uuid.wbn"
resources="urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720
urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae" />
<link rel="webbundle" href="../resources/wbn/uuid-in-package.wbn"
resources="uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae" />
<script>
const urn_bundle_url = 'https://web-platform.test:8444/web-bundle/resources/wbn/urn-uuid.wbn';
const uuid_bundle_url = 'https://web-platform.test:8444/web-bundle/resources/wbn/uuid-in-package.wbn';
function expect_violation() {
return new Promise(resolve => {
document.addEventListener('securitypolicyviolation', (e) => {
e.stopPropagation();
resolve(e);
}, {once: true});
});
}
function getReportID() {
const cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
const name_value = cookies[i].split('=');
const cookieName = name_value[0].trim();
if (cookieName === 'csp-blocked-report-id') {
return name_value[1].trim();
}
}
}
function sortReportsByEffectiveDirective(reports) {
reports.sort((report1, report2) =>
report1.body.effectiveDirective.localeCompare(report2.body.effectiveDirective)
|| report1.body.blockedURL.localeCompare(report2.body.blockedURL)
);
}
promise_test(async () => {
const p = expect_violation();
const img = document.createElement('img');
const error_promise = new Promise(resolve => {
img.onerror = resolve;
});
img.src = 'https://web-platform.test:8444/web-bundle/resources/wbn/fail.png';
document.body.appendChild(img);
const e = await p;
assert_equals(e.blockedURI, img.src);
await error_promise;
}, 'URL matching of CSP should be done based on the subresource URL, ' +
'not on the bundle URL, when the subresource URL is HTTPS URL.');
const testCases = [
{
prefix: 'urn:uuid:',
bundle_url: urn_bundle_url
},
{
prefix: 'uuid-in-package:',
bundle_url: uuid_bundle_url
}
];
for (const params of testCases) {
promise_test(async () => {
const urn_uuid = params.prefix + '020111b3-437a-4c5c-ae07-adb6bbffb720';
const p = expect_violation();
const script = document.createElement('script');
script.src = urn_uuid;
document.body.appendChild(script);
const e = await p;
// Currently Chromium is reporting the bundle URL.
// TODO(crbug.com/1208659): Consider deeper integration with CSP for
// providing the both URLs.
assert_equals(e.blockedURI, params.bundle_url);
assert_equals(e.violatedDirective, 'script-src-elem');
}, 'URL matching of script-src CSP should be done based on the bundle URL ' +
`when the subresource URL is ${params.prefix} URL.`);
promise_test(async () => {
const urn_uuid = params.prefix + '429fcc4e-0696-4bad-b099-ee9175f023ae';
const p = expect_violation();
const iframe = document.createElement('iframe');
iframe.src = urn_uuid;
const load_promise = new Promise(resolve => {
iframe.addEventListener('load', resolve);
});
document.body.appendChild(iframe);
const e = await p;
// Currently Chromium is reporting the bundle URL.
// TODO(crbug.com/1208659): Consider deeper integration with CSP for
// providing the both URLs.
assert_equals(e.blockedURI, params.bundle_url);
assert_equals(e.violatedDirective, 'frame-src');
// Make sure that the blocked iframe load is finished.
await load_promise;
// The blocked iframe is cross-origin. So accessing
// iframe.contentWindow.location should throw a SecurityError.
assert_throws_dom(
"SecurityError",
() => { iframe.contentWindow.location.href; });
}, 'URL matching of frame-src CSP should be done based on the bundle URL ' +
`when the frame URL is ${params.prefix} URL.`);
}
promise_test(async () => {
const retrieve_report_url =
"/reporting/resources/report.py?op=retrieve_report&timeout=3&reportID=" +
getReportID();
const reports = await (await fetch(retrieve_report_url)).json();
sortReportsByEffectiveDirective(reports);
assert_equals(reports.length, 5, "Report count.");
assert_equals(reports[0].body.blockedURL, urn_bundle_url);
assert_equals(reports[0].body.effectiveDirective, 'frame-src');
assert_equals(reports[1].body.blockedURL, uuid_bundle_url);
assert_equals(reports[1].body.effectiveDirective, 'frame-src');
assert_equals(
reports[2].body.blockedURL,
'https://web-platform.test:8444/web-bundle/resources/wbn/fail.png');
assert_equals(reports[2].body.effectiveDirective, 'img-src',);
assert_equals(reports[3].body.blockedURL, urn_bundle_url);
assert_equals(reports[3].body.effectiveDirective, 'script-src-elem');
assert_equals(reports[4].body.blockedURL, uuid_bundle_url);
assert_equals(reports[4].body.effectiveDirective, 'script-src-elem');
}, 'Check the CSP violation reports.');
</script>
</body>