<!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;
report-to
csp-group"
/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script type="webbundle">
{
"source": "../resources/wbn/subresource.wbn",
"resources": ["https://web-platform.test:8444/web-bundle/resources/wbn/fail.png"]
}
</script>
<script type="webbundle">
{
"source": "../resources/wbn/uuid-in-package.wbn",
"resources": ["uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720"]
}
</script>
<script>
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: "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 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, 2, "Report count.");
assert_equals(
reports[0].body.blockedURL,
"https://web-platform.test:8444/web-bundle/resources/wbn/fail.png"
);
assert_equals(reports[0].body.effectiveDirective, "img-src");
assert_equals(reports[1].body.blockedURL, uuid_bundle_url);
assert_equals(reports[1].body.effectiveDirective, "script-src-elem");
}, "Check the CSP violation reports.");
</script>
</body>