-
Notifications
You must be signed in to change notification settings - Fork 22.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> * 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 <[email protected]> * Apply suggestions from code review Co-authored-by: wbamberg <[email protected]> * 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 <[email protected]>
- Loading branch information
1 parent
59810b5
commit 51b1250
Showing
25 changed files
with
1,385 additions
and
24 deletions.
There are no files selected for viewing
219 changes: 219 additions & 0 deletions
219
files/en-us/web/api/cspviolationreportbody/blockedurl/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'" /> | ||
<script src="main.js"></script> | ||
</head> | ||
<body> | ||
<!-- This should generate a CSP violation --> | ||
<script src="https://apis.google.com/js/platform.js"></script> | ||
</body> | ||
</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 | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'" /> | ||
<script src="main.js"></script> | ||
</head> | ||
<body> | ||
<script> | ||
const int = 4; | ||
</script> | ||
</body> | ||
</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 | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta | ||
http-equiv="Content-Security-Policy" | ||
content="default-src 'self' 'report-sample' 'unsafe-inline'; trusted-types myPolicy" /> | ||
<script src="main.js"></script> | ||
</head> | ||
|
||
<body></body> | ||
|
||
<script> | ||
const policy = trustedTypes.createPolicy("somePolicy", { | ||
createHTML: (string) => { | ||
// Some (insufficient) sanitization code | ||
return string.replace(/</g, "<"); | ||
}, | ||
}); | ||
</script> | ||
</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 | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta | ||
http-equiv="Content-Security-Policy" | ||
content="default-src 'self' 'report-sample' 'unsafe-inline'; trusted-types 'myPolicy'; require-trusted-types-for 'script'" /> | ||
<script src="main.js"></script> | ||
</head> | ||
<body> | ||
<input type="text" id="userInput" /> | ||
<button onclick="updateContent()">Update Content</button> | ||
<div id="content"></div> | ||
</body> | ||
|
||
<script> | ||
function updateContent() { | ||
const userInput = document.getElementById("userInput").value; | ||
// Passing unsanitized content - a violation of the policy | ||
document.getElementById("content").innerHTML = userInput; | ||
} | ||
</script> | ||
</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(/</g, "<"); | ||
}, | ||
}); | ||
|
||
function updateContent() { | ||
const userInput = document.getElementById("userInput").value; | ||
const sanitizedInput = policy.createHTML(userInput); | ||
document.getElementById("content").innerHTML = sanitizedInput; | ||
} | ||
``` | ||
|
||
## Specifications | ||
|
||
{{Specifications}} | ||
|
||
## Browser compatibility | ||
|
||
{{Compat}} | ||
|
||
## See also | ||
|
||
- {{domxref("SecurityPolicyViolationEvent.blockedURI")}} |
120 changes: 120 additions & 0 deletions
120
files/en-us/web/api/cspviolationreportbody/columnnumber/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
--- | ||
title: "CSPViolationReportBody: columnNumber property" | ||
short-title: columnNumber | ||
slug: Web/API/CSPViolationReportBody/columnNumber | ||
page-type: web-api-instance-property | ||
browser-compat: api.CSPViolationReportBody.columnNumber | ||
--- | ||
|
||
{{APIRef("Reporting API")}} | ||
|
||
The **`columnNumber`** read-only property of the {{domxref("CSPViolationReportBody")}} interface indicates the column 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.lineNumber")}}, as it provides the location of the column in that file and line that resulted in a violation. | ||
|
||
## Value | ||
|
||
An integer containing the column 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 [`<meta>`](/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 | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta | ||
http-equiv="Content-Security-Policy" | ||
content="default-src 'self'; report-to csp-endpoint" /> | ||
<meta | ||
http-equiv="Reporting-Endpoints" | ||
content="csp-endpoint='https://example.com/csp-reports'" /> | ||
<script src="main.js"></script> | ||
<title>CSP: Violation due to inline script</title> | ||
</head> | ||
<body> | ||
<h1>CSP: Violation due to inline script</h1> | ||
<script> | ||
const int = 4; | ||
</script> | ||
</body> | ||
</html> | ||
``` | ||
|
||
#### 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 `<script>` element. | ||
|
||
## Specifications | ||
|
||
{{Specifications}} | ||
|
||
## Browser compatibility | ||
|
||
{{Compat}} | ||
|
||
## See also | ||
|
||
- {{domxref("SecurityPolicyViolationEvent.columnNumber")}} |
Oops, something went wrong.