| <!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> |