From 51b1250b1d51c2e0837c4d59798457a1261eb2af Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Sat, 21 Sep 2024 14:57:54 +1000 Subject: [PATCH] Reporting API - tidy up CSPViolationReportBody (#35602) * CSPViolationReportBody docs * SecurityPolicyViolationEvent - fix crosslinks to CSPViolationReportBody * Minor fixes to Report API top level * Code review typo fixes Co-authored-by: wbamberg * Fix code line lengths * Apply suggestions from code review * sample - aggregate the conditions. * use: that violated the [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP). * sourceFile example * Make file, line, column the same(ish) * OriginalPolicy/sourceFile example * toJSON - add JSON.stringify() * Add examples * Add example for disposition * Apply suggestions from code review - the easy ones Co-authored-by: wbamberg * Apply suggestions from code review Co-authored-by: wbamberg * Apply suggestions from code review * blockedURL fix * Apply suggestions from code review - folder from inline to test * Fix up line numbers etc * Update files/en-us/web/api/cspviolationreportbody/columnnumber/index.md * Update files/en-us/web/api/cspviolationreportbody/linenumber/index.md * Update files/en-us/web/api/cspviolationreportbody/sourcefile/index.md * Update files/en-us/web/api/cspviolationreportbody/linenumber/index.md * Update files/en-us/web/api/cspviolationreportbody/columnnumber/index.md --------- Co-authored-by: wbamberg --- .../blockedurl/index.md | 219 ++++++++++++++++++ .../columnnumber/index.md | 120 ++++++++++ .../disposition/index.md | 105 +++++++++ .../documenturl/index.md | 115 +++++++++ .../effectivedirective/index.md | 105 +++++++++ .../web/api/cspviolationreportbody/index.md | 21 +- .../linenumber/index.md | 120 ++++++++++ .../originalpolicy/index.md | 107 +++++++++ .../cspviolationreportbody/referrer/index.md | 121 ++++++++++ .../cspviolationreportbody/sample/index.md | 103 ++++++++ .../sourcefile/index.md | 123 ++++++++++ .../statuscode/index.md | 49 ++++ .../cspviolationreportbody/tojson/index.md | 64 +++++ files/en-us/web/api/reporting_api/index.md | 15 +- .../blockeduri/index.md | 2 +- .../columnnumber/index.md | 2 +- .../disposition/index.md | 2 +- .../documenturi/index.md | 2 +- .../effectivedirective/index.md | 2 +- .../linenumber/index.md | 2 +- .../originalpolicy/index.md | 2 +- .../referrer/index.md | 2 +- .../sample/index.md | 2 +- .../sourcefile/index.md | 2 +- .../statuscode/index.md | 2 +- 25 files changed, 1385 insertions(+), 24 deletions(-) create mode 100644 files/en-us/web/api/cspviolationreportbody/blockedurl/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/columnnumber/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/disposition/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/documenturl/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/effectivedirective/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/linenumber/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/originalpolicy/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/referrer/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/sample/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/sourcefile/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/statuscode/index.md create mode 100644 files/en-us/web/api/cspviolationreportbody/tojson/index.md diff --git a/files/en-us/web/api/cspviolationreportbody/blockedurl/index.md b/files/en-us/web/api/cspviolationreportbody/blockedurl/index.md new file mode 100644 index 000000000000000..f6a2128e08750cd --- /dev/null +++ b/files/en-us/web/api/cspviolationreportbody/blockedurl/index.md @@ -0,0 +1,219 @@ +--- +title: "CSPViolationReportBody: blockedURL property" +short-title: blockedURL +slug: Web/API/CSPViolationReportBody/blockedURL +page-type: web-api-instance-property +browser-compat: api.CSPViolationReportBody.blockedURL +--- + +{{APIRef("Reporting API")}} + +The **`blockedURL`** read-only property of the {{domxref("CSPViolationReportBody")}} interface is a string value that represents the resource that was blocked because it violates a [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP). + +## Value + +An string containing a value or URL that represents the resource that violated the policy. + +If the value is not the URL of a resource, it must be one of the following strings: + +- `inline` + - : An inline resource. + For example, an inline script that was used when [`'unsafe-inline'`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#unsafe-inline) was not specified in the CSP. +- `eval` + - : An `eval()`. + For example, `eval()` was used but [`'unsafe-eval'`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#unsafe-eval) was not specified in the CSP. +- `wasm-eval` + - : An WASM evaluation. + For example, `eval()` was used but [`'wasm-unsafe-eval'`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#wasm-unsafe-eval) was not specified in the CSP. +- `trusted-types-policy` + - : A resource that violated the [`trusted-types`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types) CSP directive. + For example, a {{domxref("TrustedTypePolicy")}} was created using {{domxref("TrustedTypePolicyFactory/createPolicy", "window.trustedTypes.createPolicy()")}} with a name that wasn't listed in the CSP `trusted-types` directive. +- `trusted-types-sink` + - : A resource that violated the [`require-trusted-types-for`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types) CSP directive. + For example, the directive was set to `script` but the document did not use a {{domxref("TrustedTypePolicy")}} to sanitize data before passing it to a sink such as {{domxref("Element.innerHTML")}}. + +## Examples + +The following examples show HTML that would result in some of the `blockedURL` values outlined above. + +The examples assume that you have a JavaScript file named `main.js` imported into your script from the same domain. +The script, which is shown below, creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we log the `blockedURL` in the first entry of the reports array. + +```js +const observer = new ReportingObserver( + (reports, observer) => { + console.log(`blockedURL: ${reports[0].body.blockedURL}`); + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the blocked URL of the first report. + +### blockedURL for an external resource + +The HTML below sets a policy of `Content-Security-Policy: default-src 'self'`, which only allows resources from the same site to be loaded, and then attempts to load a script from the external site `https://apis.google.com`. + +```html + + + + + + + + + + + +``` + +The result of logging the `blockedURL` would be: + +```plain +blockedURL: https://apis.google.com/js/platform.js +``` + +### blockedURL for unsafe-inline resources + +The HTML below demonstrates the conditions that would result in a `blockedURL` of `inline`. +This sets a policy of `Content-Security-Policy: default-src 'self'`, which does not allow inline scripts to be executed, causing a violation because the page contains an inline script. + +```html + + + + + + + + + + +``` + +The result of logging the `blockedURL` would be: + +```plain +blockedURL: inline +``` + +### blockedURL for trusted-types-policy resources + +The HTML below demonstrates the conditions that would result in a `blockedURL` of `trusted-types-policy`. +First it defines a policy that allows `'unsafe-inline'` scripts to be executed, so that we can create a {{domxref("TrustedTypePolicy")}} that will trigger a violation. +The policy also uses the `trusted-types` directive to specify that a {{domxref("TrustedTypePolicy")}} with the name `myPolicy` is allowed to be created. + +```html + + + + + + + + + + + +``` + +In the script a policy is created with the name `somePolicy`. + +> [!NOTE] +> The particular policy we defined above is not a very good policy. +> The aim of using trusted types is not to enforce a _particular_ policy, but to require enforcement of some policy, and ensure that the sanitization code is in one place and easy to review. + +Because this is not listed in the `trusted-types` directive it is a CSP violation, and we'd see the log output: + +```plain +blockedURL: trusted-types-policy +``` + +If we changed the name of the allowed policy to `somePolicy`, the page would no longer be in violation. + +### blockedURL for trusted-types-sink resources + +The HTML below demonstrates the conditions that would result in a `blockedURL` of `trusted-types-sink`. +First it defines a policy that allows `'unsafe-inline'` scripts to be executed, and as in the previous example it use the `trusted-types` directive to specify that a {{domxref("TrustedTypePolicy")}} with the name `myPolicy` is allowed to be created. + +In addition, it specifies the directive `require-trusted-types-for 'script'`, which enforces that sinks should only be passed content that has been sanitized using a trusted type. + +```html + + + + + + + + + +
+ + + + +``` + +The `updateContent()` method passes unsanitized content to the element's `innerHTML` property, which will cause a CSP violation. +We'd see the log output: + +```plain +blockedURL: trusted-types-sink +``` + +In order to avoid the violation we would need to update the script to define a trusted type policy, and use it to sanitize the input passed to the element: + +```js +const policy = trustedTypes.createPolicy("myPolicy", { + createHTML: (string) => { + // Some (insufficient) sanitization code + return string.replace(/`](/en-US/docs/Web/HTML/Element/meta) element to set the {{httpheader('Content-Security-Policy')}} `default-src` to `self`, which allows scripts and other resources to be loaded from the same origin, but does not allow inline scripts to be executed. +The document also includes an inline script, which should therefore trigger a CSP violation. + +```html + + + + + + + CSP: Violation due to inline script + + +

CSP: Violation due to inline script

+ + + +``` + +#### JavaScript (main.js) + +The document above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the file, line, and column of the violation to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + const cspViolationBody = reports[0].body; + console.log(`sourceFile: ${cspViolationBody.sourceFile}`); + console.log(`lineNumber: ${cspViolationBody.lineNumber}`); + console.log(`columnNumber: ${cspViolationBody.columnNumber}`); + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +You can try this out using a [local server](/en-US/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server). +Copy the above code into `test/index.html` and `test/main.js` and run the server in the root directory. +Assuming the address of the local server is `http://127.0.0.1:9999`, you can then load the HTML file from `http://127.0.0.1:9999/test/` (or `http://127.0.0.1:9999/test/index.html`). + +With the above setup, the output of the log on Chrome is: + +```plain +sourceFile: http://127.0.0.1:9999/test/ +lineNumber: 15 +columnNumber: 0 +``` + +The result is similar for Firefox: + +```plain +sourceFile: http://127.0.0.1:9999/test/ +lineNumber: 15 +columnNumber: 13 +``` + +Note that the column number is different for the two browsers. +Chrome always appears to report `0`. +The value on Firefox represents the position of the first character after the end of the opening ` + CSP: Violation due to inline script + + +

CSP: Violation due to inline script

+ + + +``` + +#### JavaScript (main.js) + +The document above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the file, line, and column of the violation to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + const cspViolationBody = reports[0].body; + console.log(`disposition: ${cspViolationBody.disposition}`); + // For example: "enforce" + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +If serving the above code, the log output would be: + +```plain +disposition: enforce +``` + +> [!NOTE] +> If `Content-Security-Policy-Reporting-Only` was enabled the disposition would be `report`. +> Note however, that `Content-Security-Policy-Reporting-Only` must be served: it can't be set in the `` element as we have done above. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("SecurityPolicyViolationEvent.disposition")}} diff --git a/files/en-us/web/api/cspviolationreportbody/documenturl/index.md b/files/en-us/web/api/cspviolationreportbody/documenturl/index.md new file mode 100644 index 000000000000000..298e2c87221bbf1 --- /dev/null +++ b/files/en-us/web/api/cspviolationreportbody/documenturl/index.md @@ -0,0 +1,115 @@ +--- +title: "CSPViolationReportBody: documentURL property" +short-title: documentURL +slug: Web/API/CSPViolationReportBody/documentURL +page-type: web-api-instance-property +browser-compat: api.CSPViolationReportBody.documentURL +--- + +{{APIRef("Reporting API")}} + +The **`documentURL`** read-only property of the {{domxref("CSPViolationReportBody")}} interface is a string that represents the URL of the document or worker that violated the [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP). + +## Value + +A string containing the URL of the document or worker that violated the CSP. + +## Examples + +### CSP inline script violation showing referrer + +This example triggers a CSP violation using an inline script, and reports the violation using a {{domxref("ReportingObserver")}}. +We navigate to the page from another page and log the `referrer`, `documentURL`, and `blockedURL`. + +#### HTML + +First we define our referrer page `/bounce/index.html`. +This page just contains a link to another page `../report_sample/index.html`. + +```html + + + + + + + + + + +``` + +The `../report_sample/index.html` HTML file is defined below. +This uses the [``](/en-US/docs/Web/HTML/Element/meta) element to set the {{httpheader('Content-Security-Policy')}} `script-src-elem` to `self`, which allows scripts to be loaded from the same domain, but does not allow inline scripts to be executed. +The document also includes an inline script, which will trigger a CSP violation. + +```html + + + + + + + + + + + +``` + +#### JavaScript (main.js) + +The report sample above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the violation `documentURL`, `referrer`, and `blockedURL` to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + console.log(`documentURL: ${reports[0].body.referrer}`); + console.log(`referrer: ${reports[0].body.referrer}`); + console.log(`blockedURL: ${reports[0].body.blockedURL}`); + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +The console output for the above code would look a bit like that below (the site will depend on how the pages are served): + +```plain +documentURL: http://127.0.0.1:9999/report_sample/ +referrer: http://127.0.0.1:9999/bounce/ +blockedURL: inline +``` + +Note that `referrer` is the page we navigated from, `documentURL` is the page with the CSP violation, and `blockedURL` is not an URL at all in this case, but an indication that the violation was caused by an inline script. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("SecurityPolicyViolationEvent.documentURI")}} diff --git a/files/en-us/web/api/cspviolationreportbody/effectivedirective/index.md b/files/en-us/web/api/cspviolationreportbody/effectivedirective/index.md new file mode 100644 index 000000000000000..a0169c932d0351e --- /dev/null +++ b/files/en-us/web/api/cspviolationreportbody/effectivedirective/index.md @@ -0,0 +1,105 @@ +--- +title: "CSPViolationReportBody: effectiveDirective property" +short-title: effectiveDirective +slug: Web/API/CSPViolationReportBody/effectiveDirective +page-type: web-api-instance-property +browser-compat: api.CSPViolationReportBody.effectiveDirective +--- + +{{APIRef("Reporting API")}} + +The **`effectiveDirective`** read-only property of the {{domxref("CSPViolationReportBody")}} interface is a string that represents the effective [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP) directive that was violated. + +Note that this contains the specific directive that was effectively violated, such as [`script-src-elem`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src-elem) for violations related to script elements, and not the policy that was specified, which may have been the (more general) [`default-src`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src). + +## Value + +A string representing the effective [`Content-Security-Policy` directive](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#directives) that was violated. + +## Examples + +### CSP inline script violation + +This example triggers a CSP violation using an inline script, and reports the violation using a {{domxref("ReportingObserver")}}. +In particular, it logs the `effectiveDirective` and the `originalPolicy`, making the difference clear. + +#### HTML + +The HTML file below uses the [``](/en-US/docs/Web/HTML/Element/meta) element to set the {{httpheader('Content-Security-Policy')}} `default-src` to `self`, which allows scripts and other resources to be loaded from the same domain, but does not allow inline scripts to be executed. +The document also includes an inline script, which should trigger a CSP violation. + +```html + + + + + + + CSP: Violation due to inline script + + +

CSP: Violation due to inline script

+ + + +``` + +#### JavaScript (main.js) + +The document above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the effectiveDirective and `originalPolicy` of the violation to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + console.log(`effectiveDirective: ${reports[0].body.effectiveDirective}`); + // effectiveDirective: script-src-elem + console.log(`originalPolicy: ${reports[0].body.originalPolicy}`); + // originalPolicy: default-src 'self'; report-to csp-endpoint + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +The console output for the above code is: + +```plain +effectiveDirective: script-src-elem +originalPolicy: default-src 'self'; report-to csp-endpoint +``` + +Note that the `orginalPolicy` matches the `` content of the `Content-Security-Policy` directive in the HTML, and specifies that the policy is `self` by default (`default-src 'self'`). + +The `effectiveDirective` is `script-src-elem`, which specifies valid sources for JavaScript {{htmlelement("script")}} elements. +This is the specific directive that has effectively been violated, even though `default-src` was set in the policy. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("SecurityPolicyViolationEvent.effectiveDirective")}} diff --git a/files/en-us/web/api/cspviolationreportbody/index.md b/files/en-us/web/api/cspviolationreportbody/index.md index e4a5311f9593fb4..b3919a74b631e36 100644 --- a/files/en-us/web/api/cspviolationreportbody/index.md +++ b/files/en-us/web/api/cspviolationreportbody/index.md @@ -28,7 +28,7 @@ These reports similarly have a `type` of `"csp-violation"`, and a `body` propert _Also inherits properties from its parent interface, {{DOMxRef("ReportBody")}}._ - {{domxref("CSPViolationReportBody.blockedURL")}} {{ReadOnlyInline}} - - : A string representing the URL of the resource that was blocked because it violates the CSP. + - : A string representing either the type or the URL of the resource that was blocked because it violates the CSP. - {{domxref("CSPViolationReportBody.columnNumber")}} {{ReadOnlyInline}} - : The column number in the script at which the violation occurred. - {{domxref("CSPViolationReportBody.disposition")}} {{ReadOnlyInline}} @@ -64,12 +64,18 @@ _Also inherits methods from its parent interface, {{DOMxRef("ReportBody")}}._ To obtain a `CSPViolationReportBody` object, you must configure your page so that a CSP violation will occur. In this example, we will set our CSP to only allow content from the site's own origin, and then attempt to load a script from `apis.google.com`, which is an external origin. -First, we will set our {{HTTPHeader("Content-Security-Policy")}} header: +First, we will set our {{HTTPHeader("Content-Security-Policy")}} header in the HTTP response: ```http Content-Security-Policy: default-src 'self'; ``` +or in the HTML [``](/en-US/docs/Web/HTML/Element/meta) element: + +```html + +``` + Then, we will attempt to load an external script: ```html @@ -82,7 +88,10 @@ Finally, we will create a new {{domxref("ReportingObserver")}} object to listen ```js const observer = new ReportingObserver( (reports, observer) => { - const cspViolation = reports[0]; + reports.forEach((violation) => { + console.log(violation); + console.log(JSON.stringify(violation)); + }); }, { types: ["csp-violation"], @@ -93,7 +102,7 @@ const observer = new ReportingObserver( observer.observe(); ``` -If we were to log the violation report object, it would look similar to the object below. +Above we log the each violation report object and a JSON-string version of the object, which might look similar to the object below. Note that the `body` is an instance of the `CSPViolationReportBody` and the `type` is `"csp-violation"`. ```js @@ -130,7 +139,7 @@ Reporting-Endpoints: csp-endpoint="https://example.com/csp-report-to" Content-Security-Policy: default-src 'self'; report-to csp-endpoint ``` -As before, we can trigger the violation by loading an external script from a location that is not allowed by our CSP header: +As before, we can trigger a violation by loading an external script from a location that is not allowed by our CSP header: ```html @@ -153,7 +162,7 @@ As you can see from the example below, the `type` is `"csp-violation"` and the ` "lineNumber": 1441, "originalPolicy": "default-src 'self'; report-to csp-endpoint", "referrer": "https://www.google.com/", - "sample": "console.log(\"lo\")", + "sample": "", "sourceFile": "https://example.com/csp-report-to", "statusCode": 200 }, diff --git a/files/en-us/web/api/cspviolationreportbody/linenumber/index.md b/files/en-us/web/api/cspviolationreportbody/linenumber/index.md new file mode 100644 index 000000000000000..debe2ebbf9f2da0 --- /dev/null +++ b/files/en-us/web/api/cspviolationreportbody/linenumber/index.md @@ -0,0 +1,120 @@ +--- +title: "CSPViolationReportBody: lineNumber property" +short-title: lineNumber +slug: Web/API/CSPViolationReportBody/lineNumber +page-type: web-api-instance-property +browser-compat: api.CSPViolationReportBody.lineNumber +--- + +{{APIRef("Reporting API")}} + +The **`lineNumber`** read-only property of the {{domxref("CSPViolationReportBody")}} interface indicates the line number in the source file that triggered the [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP) violation. + +Note that the browser extracts the value from _the global object_ of the file that triggered the violation. +If the resource that triggers the CSP violation is not loaded, the value will be `null`. +See {{domxref("CSPViolationReportBody.sourceFile")}} for more information. + +This property is most useful alongside {{domxref("CSPViolationReportBody.sourceFile")}} and {{domxref("CSPViolationReportBody.columnNumber")}}, as it provides the location of the line in that file and the column that resulted in a violation. + +## Value + +An integer containing the line number that triggered the violation, or `null`. + +## Examples + +### CSP inline script violation + +This example triggers a CSP violation using an inline script, and reports the violation using a {{domxref("ReportingObserver")}}. + +#### HTML + +The HTML file below uses the [``](/en-US/docs/Web/HTML/Element/meta) element to set the {{httpheader('Content-Security-Policy')}} `default-src` to `self`, which allows scripts and other resources to be loaded from the same origin, but does not allow inline scripts to be executed. +The document also includes an inline script, which should therefore trigger a CSP violation. + +```html + + + + + + + CSP: Violation due to inline script + + +

CSP: Violation due to inline script

+ + + +``` + +#### JavaScript (main.js) + +The document above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the file, line, and column of the violation to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + const cspViolationBody = reports[0].body; + console.log(`sourceFile: ${cspViolationBody.sourceFile}`); + console.log(`lineNumber: ${cspViolationBody.lineNumber}`); + console.log(`columnNumber: ${cspViolationBody.columnNumber}`); + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +You can try this out using a [local server](/en-US/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server). +Copy the above code into `test/index.html` and `test/main.js` and run the server in the root directory. +Assuming the address of the local server is `http://127.0.0.1:9999`, you can then load the HTML file from `http://127.0.0.1:9999/test/` (or `http://127.0.0.1:9999/test/index.html`). + +With the above setup, the output of the log on Chrome is: + +```plain +sourceFile: http://127.0.0.1:9999/test/ +lineNumber: 15 +columnNumber: 0 +``` + +The result is similar for Firefox: + +```plain +sourceFile: http://127.0.0.1:9999/test/ +lineNumber: 15 +columnNumber: 13 +``` + +Note that the column number is different for the two browsers. +Chrome always appears to report `0`. +The value on Firefox represents the position of the first character after the end of the opening ` + CSP: Violation due to inline script + + +

CSP: Violation due to inline script

+ + + +``` + +#### JavaScript (main.js) + +The document above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the effectiveDirective and `originalPolicy` of the violation to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + console.log(`effectiveDirective: ${reports[0].body.effectiveDirective}`); + // effectiveDirective: script-src-elem + console.log(`originalPolicy: ${reports[0].body.originalPolicy}`); + // originalPolicy: default-src 'self'; report-to csp-endpoint + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +The console output for the above code is: + +```plain +effectiveDirective: script-src-elem +originalPolicy: default-src 'self'; report-to csp-endpoint +``` + +Note that the `orginalPolicy` matches the `` content of the `Content-Security-Policy` directive in the HTML, and specifies that the policy is `self` by default (`default-src 'self'`). + +The `effectiveDirective` is `script-src-elem`, which specifies valid sources for JavaScript {{htmlelement("script")}} elements. +This is the specific directive that has effectively been violated, even though `default-src` was set in the policy. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("SecurityPolicyViolationEvent.originalPolicy")}} diff --git a/files/en-us/web/api/cspviolationreportbody/referrer/index.md b/files/en-us/web/api/cspviolationreportbody/referrer/index.md new file mode 100644 index 000000000000000..f04a3924e4680bd --- /dev/null +++ b/files/en-us/web/api/cspviolationreportbody/referrer/index.md @@ -0,0 +1,121 @@ +--- +title: "CSPViolationReportBody: referrer property" +short-title: referrer +slug: Web/API/CSPViolationReportBody/referrer +page-type: web-api-instance-property +browser-compat: api.CSPViolationReportBody.referrer +--- + +{{APIRef("Reporting API")}} + +The **`referrer`** read-only property of the {{domxref("CSPViolationReportBody")}} interface is a string that represents the URL of the referring page of the resource who's [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP) was violated. + +The referrer is the page that caused the page with the CSP violation to be loaded. For example, if we followed a link to a page with a CSP violation, the `referrer` is the page that we navigated from. + +## Value + +A string representing the URL for the referrer of the page with the CSP violation, or null. + +Note that if the referrer is an HTTP(S) URL then any username, password or fragment is removed. +If the URL scheme is not `http:` or `https:` then just the scheme is returned. + +## Examples + +### CSP inline script violation showing referrer + +This example triggers a CSP violation using an inline script, and reports the violation using a {{domxref("ReportingObserver")}}. +We navigate to the page from another page and log the `referrer`, `documentURL`, and `blockedURL`. + +#### HTML + +First we define our referrer page `/bounce/index.html`. +This page just contains a link to another page `../report_sample/index.html`. + +```html + + + + + + + + + + +``` + +The `../report_sample/index.html` HTML file is defined below. +This uses the [``](/en-US/docs/Web/HTML/Element/meta) element to set the {{httpheader('Content-Security-Policy')}} `script-src-elem` to `self`, which allows scripts to be loaded from the same domain, but does not allow inline scripts to be executed. +The document also includes an inline script, which will trigger a CSP violation. + +```html + + + + + + + + + + + +``` + +#### JavaScript (main.js) + +The report sample above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the violation `documentURL`, `referrer`, and `blockedURL` to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + console.log(`documentURL: ${reports[0].body.referrer}`); + console.log(`referrer: ${reports[0].body.referrer}`); + console.log(`blockedURL: ${reports[0].body.blockedURL}`); + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +The console output for the above code would look a bit like that below (the site will depend on how the pages are served): + +```plain +documentURL: http://127.0.0.1:9999/report_sample/ +referrer: http://127.0.0.1:9999/bounce/ +blockedURL: inline +``` + +Note that `referrer` is the page we navigated from, `documentURL` is the page with the CSP violation, and `blockedURL` is not an URL at all in this case, but an indication that the violation was caused by an unsafe inline script. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("SecurityPolicyViolationEvent.referrer")}} +- {{httpheader("Referer")}} diff --git a/files/en-us/web/api/cspviolationreportbody/sample/index.md b/files/en-us/web/api/cspviolationreportbody/sample/index.md new file mode 100644 index 000000000000000..8dd858e9fbc3b5f --- /dev/null +++ b/files/en-us/web/api/cspviolationreportbody/sample/index.md @@ -0,0 +1,103 @@ +--- +title: "CSPViolationReportBody: sample property" +short-title: sample +slug: Web/API/CSPViolationReportBody/sample +page-type: web-api-instance-property +browser-compat: api.CSPViolationReportBody.sample +--- + +{{APIRef("Reporting API")}} + +The **`sample`** read-only property of the {{domxref("CSPViolationReportBody")}} interface is a string that contains a part of the resource that violated the [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP). + +This sample is usually the first 40 characters of the inline script, event handler, or style that violated a CSP restriction. +If not populated it is the empty string `""`. + +Note that this is only populated when attempting to load _inline_ scripts, event handlers, or styles that violate CSP [`script-src*`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#script-src) and [`style-src*`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#style-src) rules — external resources that violate the CSP will not generate a sample. +In addition, a sample is only included if the `Content-Security-Policy` directive that was violated also contains the [`'report-sample'`](/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#report-sample) keyword. + +> [!NOTE] Violation reports should be considered attacker-controlled data. +> The content of this field _in particular_ should be sanitized before storing or rendering. + +## Value + +A string containing a sample of the inline resource that violated the CSP, usually the first 40 characters, or the empty string. + +## Examples + +### CSP inline script violation + +This example triggers a CSP violation using an inline script, and reports the violation using a {{domxref("ReportingObserver")}}. +We also add `'report-sample'` to the CSP in order to populate a `sample` in the body. + +#### HTML + +The HTML file below uses the [``](/en-US/docs/Web/HTML/Element/meta) element to set the {{httpheader('Content-Security-Policy')}} `script-src-elem` to `self`, which allows scripts to be loaded from the same domain, but does not allow inline scripts to be executed. +We include `'report-sample'` in the directive so that a sample is generated. +The document also includes an inline script, which should trigger a CSP violation. + +```html + + + + + + CSP: Violation due to inline script + + +

CSP: Violation due to inline script

+ + + +``` + +#### JavaScript (main.js) + +The document above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the violation `sample` to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + console.log(`sample: ${reports[0].body.sample}`); + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +The console output for the above code is: + +```plain +sample: const int = 4; +``` + +In this case the sample contains the entire content of the inline script. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("SecurityPolicyViolationEvent.sample")}} diff --git a/files/en-us/web/api/cspviolationreportbody/sourcefile/index.md b/files/en-us/web/api/cspviolationreportbody/sourcefile/index.md new file mode 100644 index 000000000000000..d410b432654c4a8 --- /dev/null +++ b/files/en-us/web/api/cspviolationreportbody/sourcefile/index.md @@ -0,0 +1,123 @@ +--- +title: "CSPViolationReportBody: sourceFile property" +short-title: sourceFile +slug: Web/API/CSPViolationReportBody/sourceFile +page-type: web-api-instance-property +browser-compat: api.CSPViolationReportBody.sourceFile +--- + +{{APIRef("Reporting API")}} + +The **`sourceFile`** read-only property of the {{domxref("CSPViolationReportBody")}} interface indicates the URL of the source file that violated the [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP). + +For a violation triggered by the use of an inline script, `sourceFile` is the URL of the current document. +Similarly, if a document successfully loads a script that then violates the document CSP, the `sourceFile` is the URL of the script. + +Note however that if a document with a CSP that blocks external resources attempts to load an external resource, `sourceFile` will be `null`. +This is because the browser extracts the value from _the global object_ of the file that triggered the violation. +Because of the CSP restriction the external resource is never loaded, and therefore has no corresponding global object. + +This property is most useful alongside {{domxref("CSPViolationReportBody.lineNumber")}} and {{domxref("CSPViolationReportBody.columnNumber")}}, which provide the location within the file that resulted in a violation. + +## Value + +A string containing the URL of the file that triggered the violation, or `null`. + +## Examples + +### CSP inline script violation + +This example triggers a CSP violation using an inline script, and reports the violation using a {{domxref("ReportingObserver")}}. + +#### HTML + +The HTML file below uses the [``](/en-US/docs/Web/HTML/Element/meta) element to set the {{httpheader('Content-Security-Policy')}} `default-src` to `self`, which allows scripts and other resources to be loaded from the same origin, but does not allow inline scripts to be executed. +The document also includes an inline script, which should therefore trigger a CSP violation. + +```html + + + + + + + CSP: Violation due to inline script + + +

CSP: Violation due to inline script

+ + + +``` + +#### JavaScript (main.js) + +The document above also loads the external script `main.js`, which is shown below. +Because this is loaded from the same domain as the HTML, it is not blocked by the CSP. + +The script creates a new {{domxref("ReportingObserver")}} to observe content violation reports of type `"csp-violation"`. +Each time the callback function is invoked, we get the body of the first entry of the reports array, and use it to log the file, line, and column of the violation to the console. + +```js +// main.js +const observer = new ReportingObserver( + (reports, observer) => { + const cspViolationBody = reports[0].body; + console.log(`sourceFile: ${cspViolationBody.sourceFile}`); + console.log(`lineNumber: ${cspViolationBody.lineNumber}`); + console.log(`columnNumber: ${cspViolationBody.columnNumber}`); + }, + { + types: ["csp-violation"], + buffered: true, + }, +); + +observer.observe(); +``` + +Note that while there might be multiple reports in the returned array, for brevity we only log the values of the first element. + +#### Results + +You can try this out using a [local server](/en-US/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server). +Copy the above code into `test/index.html` and `test/main.js` and run the server in the root directory. +Assuming the address of the local server is `http://127.0.0.1:9999`, you can then load the HTML file from `http://127.0.0.1:9999/test/` (or `http://127.0.0.1:9999/test/index.html`). + +With the above setup, the output of the log on Chrome is: + +```plain +sourceFile: http://127.0.0.1:9999/test/ +lineNumber: 15 +columnNumber: 0 +``` + +The result is similar for Firefox: + +```plain +sourceFile: http://127.0.0.1:9999/test/ +lineNumber: 15 +columnNumber: 13 +``` + +Note that the column number is different for the two browsers. +Chrome always appears to report `0`. +The value on Firefox represents the position of the first character after the end of the opening `