Skip to content

Commit 2d0aa21

Browse files
authored
COEP reporting documentation (mdn#39880)
1 parent 21ece11 commit 2d0aa21

File tree

4 files changed

+394
-17
lines changed

4 files changed

+394
-17
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
---
2+
title: COEPViolationReport
3+
slug: Web/API/COEPViolationReport
4+
page-type: web-api-interface
5+
browser-compat: api.ReportingObserver.ReportingObserver.options_parameter.types_property.coep
6+
spec-urls:
7+
- https://html.spec.whatwg.org/multipage/browsers.html#embedder-policy-checks
8+
- https://html.spec.whatwg.org/multipage/browsers.html#coep
9+
---
10+
11+
{{APIRef("Reporting API")}}
12+
13+
The `COEPViolationReport` dictionary of the [Reporting API](/en-US/docs/Web/API/Reporting_API) represents a report generated when a document violates its {{httpheader("Cross-Origin-Embedder-Policy")}} (COEP).
14+
15+
Reports of this type can be observed from within a page using a {{domxref("ReportingObserver")}}, or a serialized version can be sent to a [reporting server endpoint](/en-US/docs/Web/API/Reporting_API#reporting_server_endpoints).
16+
17+
## Instance properties
18+
19+
- `body`
20+
- : The body of the report, containing more information about the violation.
21+
This is an object with the following properties:
22+
- `type`
23+
- : A string representing the cause of the violation that triggered the report.
24+
This can have one of the following values:
25+
- `"corp"`
26+
- : A document with {{httpheader("Cross-Origin-Embedder-Policy")}} set to [`require-corp`](/en-US/docs/Web/HTTP/Reference/Headers/Cross-Origin-Embedder-Policy#require-corp) attempted to load a cross-origin sub-resource that does not explicitly allow itself to be embedded (by setting an appropriate {{httpheader("Cross-Origin-Resource-Policy")}}).
27+
- `"navigation"`
28+
- : An {{htmlelement("iframe")}} in a document that has either COEP `require-corp` or `credentialless` directives loads a document that:
29+
- Has neither the COEP `require-corp` nor `credentialless` directive
30+
- Is cross-origin with the embedding document, and does not have a CORP header that allows embedding in the parent
31+
- `"worker initialization"`
32+
- : A dedicated worker created by a document with either the COEP `require-corp` or `credentialless` directives tries to load a worker script with neither of these set.
33+
34+
- `blockedURL`
35+
- : A string containing the URL of the resource that was blocked from loading by an enforced COEP violation.
36+
- `destination` {{non-standard_inline}}
37+
- : A string indicating the _destination_ of the blocked resource.
38+
This can have one of the values of [`Request.destination`](/en-US/docs/Web/API/Request/destination#value).
39+
- `disposition`
40+
- : A string indicating whether the violation was enforced or only reported.
41+
This can have one of the following values:
42+
- `"enforce"`
43+
- : The violation caused loading of the embedded resource to be blocked.
44+
This is set for violations of policies set with {{httpheader("Cross-Origin-Embedder-Policy")}}.
45+
- `"reporting"`
46+
- : The violation was reported without blocking the resource from loading.
47+
This is set for violations of policies set with {{httpheader("Cross-Origin-Embedder-Policy-Report-Only")}}.
48+
49+
- `type`
50+
- : The string `"coep"`, indicating that this is a COEP violation report.
51+
52+
- `url`
53+
- : A string representing the URL of the document that generated the report.
54+
55+
## Description
56+
57+
A document's policies for loading and embedding cross-origin resources that are requested in `no-cors` mode are configured and enforced using the {{httpheader("Cross-Origin-Embedder-Policy")}} HTTP header, and may also be reported but not enforced using the {{httpheader("Cross-Origin-Embedder-Policy-Report-Only")}} header.
58+
59+
COEP policy violations may be reported whenever a policy set by those headers blocks (or would block) the loading of a resource.
60+
61+
You can monitor for COEP violation reports within the page that sets the policy using the [Reporting API](/en-US/docs/Web/API/Reporting_API).
62+
To do this you create a {{domxref("ReportingObserver")}} object to listen for reports, passing a callback method and an (optional) `options` property specifying the types of reports that you want to report on.
63+
The callback method is then called with reports of the requested types, passing a report object.
64+
For COEP violations, the object will be a `COEPViolationReport` (which has the [`type`](#type) property set to `"coep"`).
65+
66+
The structure of a typical report is shown below.
67+
Note that we can see the URL of both the page that had its policy violated (`url`) and the resource that was blocked from loading (`body.blockedURL`).
68+
We can also see that the report was triggered by a `corp` violation, and from the `body.disposition` that it was enforced (and not just reported).
69+
70+
```json
71+
{
72+
"type": "coep",
73+
"url": "https://url-of-page-attempting-to-load-resource-in-violation",
74+
"body": {
75+
"type": "corp",
76+
"blockedURL": "https://url-of-blocked-resource",
77+
"destination": "image",
78+
"disposition": "enforce"
79+
}
80+
}
81+
```
82+
83+
Violation reports may also be sent as a JSON object in a `POST` to a configured [reporting server endpoint](/en-US/docs/Web/API/Reporting_API#reporting_server_endpoints).
84+
The reporting server endpoint name is specified in the [`report-to`](/en-US/docs/Web/HTTP/Reference/Headers/Cross-Origin-Embedder-Policy#report-to_endpoint_name) policy directive of the {{httpheader("Cross-Origin-Embedder-Policy")}} or {{httpheader("Cross-Origin-Embedder-Policy-Report-Only")}} header.
85+
Valid endpoint names and their mapping to a particular URL are defined using the {{httpheader("Reporting-Endpoints")}} header.
86+
87+
The structure of the server report is almost exactly the same as `COEPViolationReport`, except that it additionally includes `age` and `user_agent` fields.
88+
89+
```json
90+
[
91+
{
92+
"age": 967132,
93+
"body": {
94+
"blockedURL": "https://url-of-resource-that-was-blocked",
95+
"destination": "image",
96+
"disposition": "enforce",
97+
"type": "corp"
98+
},
99+
"type": "coep",
100+
"url": "https://url-of-document-that-generated-report",
101+
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
102+
}
103+
]
104+
```
105+
106+
## Examples
107+
108+
### Using the `ReportingObserver` interface
109+
110+
This example shows how you can obtain COEP violation reports using a {{domxref("ReportingObserver")}}.
111+
112+
First consider the case where we have an HTML file hosted on the origin `https://example.com`, which includes an {{htmlelement("img")}} element that sets as its source the (cross-origin) resource `some-image.png`.
113+
Since the element does not set the [`crossorigin`](/en-US/docs/Web/HTML/Reference/Attributes/crossorigin) attribute, it will be requested in `no-cors` mode.
114+
By default, if `some-image.png` is not served with the {{httpheader("Cross-Origin-Embedder-Policy")}} header, this request will succeed.
115+
116+
```html
117+
<img src="https://another-example.com/some-image.png" />
118+
```
119+
120+
In order to ensure that the document only loads cross-origin resources that indicate that they are safe to load in our document origin, we can set the {{httpheader("Cross-Origin-Embedder-Policy")}} header with the [`require-corp`](/en-US/docs/Web/HTTP/Reference/Headers/Cross-Origin-Embedder-Policy#require-corp) directive as shown:
121+
122+
```http
123+
Cross-Origin-Embedder-Policy: require-corp
124+
```
125+
126+
This header enforces that all resources must be served with the {{HTTPHeader("Cross-Origin-Resource-Policy")}} header and a value of `cross-origin` in order to be loaded into the document's origin (`https://example.com`).
127+
Provided the server hosting `some-image.png` doesn't set the header, we don't need to do anything else to trigger a COEP violation.
128+
129+
To observe violations within the page, we construct a new {{domxref("ReportingObserver")}} object to listen for reports with the type `"coep"`, passing a callback that will receive and log the reports.
130+
This code needs to be loaded before the script that causes the violation:
131+
132+
```js
133+
const options = {
134+
types: ["coep"],
135+
buffered: true,
136+
};
137+
138+
const observer = new ReportingObserver((reports, observer) => {
139+
reports.forEach((violation) => {
140+
console.log(violation);
141+
console.log(JSON.stringify(violation));
142+
});
143+
}, options);
144+
145+
observer.observe();
146+
```
147+
148+
Above, we log each violation report object and a JSON-string version of the object, which might look similar to the object below.
149+
Note that the `type` is `"coep"`.
150+
151+
```json
152+
{
153+
"type": "coep",
154+
"url": "https://example.com",
155+
"body": {
156+
"type": "corp",
157+
"blockedURL": "https://another-example.com/some-image.png",
158+
"destination": "image",
159+
"disposition": "enforce"
160+
}
161+
}
162+
```
163+
164+
The same report could be generated using {{httpheader("Cross-Origin-Embedder-Policy-Report-Only")}}, except that the [disposition](#disposition) would be reported as `"reporting"`.
165+
166+
### Sending a report to a reporting endpoint
167+
168+
Configuring a web page to send a COEP report to a [reporting server endpoint](/en-US/docs/Web/API/Reporting_API#reporting_server_endpoints) is almost the same as the previous example.
169+
The only difference is that we need to specify a reporting endpoint where we want the reports to be sent, using the {{httpheader("Reporting-Endpoints")}} response header, and then reference these in the `report-to` parameter when setting the policy.
170+
171+
You can see this below, where we define the endpoint named `coep-endpoint` and then reference it in our policy:
172+
173+
```http
174+
Reporting-Endpoints: coep-endpoint="https://some-example.com/coep"
175+
Cross-Origin-Embedder-Policy: require-corp; report-to="coep-endpoint"
176+
```
177+
178+
The violation report will then be sent as a JSON object in a `POST` to the endpoint referenced by `coep-endpoint`.
179+
180+
The report object has the same structure as returned from the `ReportingObserver` callback except for the addition of `age` and `user_agent` properties.
181+
182+
```json
183+
[
184+
{
185+
"age": 717139,
186+
"body": {
187+
"blockedURL": "https://another-example.com/some-image.png",
188+
"destination": "image",
189+
"disposition": "enforce",
190+
"type": "corp"
191+
},
192+
"type": "coep",
193+
"url": "https://example.com",
194+
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
195+
}
196+
]
197+
```
198+
199+
The same report would be generated if we set {{httpheader("Cross-Origin-Embedder-Policy-Report-Only")}} in the same way, except that the [disposition](#disposition) would be set to `"reporting"`.
200+
201+
## Specifications
202+
203+
{{Specifications}}
204+
205+
## Browser compatibility
206+
207+
{{Compat}}
208+
209+
## See also
210+
211+
- {{domxref("ReportingObserver")}}
212+
- {{httpheader("Cross-Origin-Embedder-Policy")}}
213+
- {{httpheader("Cross-Origin-Embedder-Policy-Report-Only")}}
214+
- {{HTTPHeader("Reporting-Endpoints")}}
215+
- [Reporting API](/en-US/docs/Web/API/Reporting_API)
216+
- [The Reporting API](https://developer.chrome.com/docs/capabilities/web-apis/reporting-api) (developer.chrome.com)
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
title: Cross-Origin-Embedder-Policy-Report-Only (COEP) header
3+
short-title: Cross-Origin-Embedder-Policy-Report-Only
4+
slug: Web/HTTP/Reference/Headers/Cross-Origin-Embedder-Policy-Report-Only
5+
page-type: http-header
6+
browser-compat: http.headers.Cross-Origin-Embedder-Policy
7+
sidebar: http
8+
---
9+
10+
The HTTP **`Cross-Origin-Embedder-Policy-Report-Only`** (COEP) {{Glossary("response header")}} configures the current document's _report-only_ policy for loading and embedding cross-origin resources that are requested in `no-cors` mode.
11+
12+
The header allows website administrators to report on resources that would be blocked by {{HTTPHeader("Cross-Origin-Embedder-Policy")}}, without preventing them from being loaded.
13+
This allows for a softer rollout of enforcement.
14+
15+
Violations of the policy may be reported using the [Reporting API](/en-US/docs/Web/API/Reporting_API).
16+
Reports can be observed in the page for which the policy is being set using a [`ReportingObserver`](/en-US/docs/Web/API/ReportingObserver), and sent to server endpoints defined in a {{HTTPHeader("Reporting-Endpoints")}} HTTP response header, and selected using the [`report-to`](#report-to_endpoint_name) parameter.
17+
For more information see {{domxref("COEPViolationReport")}}.
18+
19+
<table class="properties">
20+
<tbody>
21+
<tr>
22+
<th scope="row">Header type</th>
23+
<td>{{Glossary("Response header")}}</td>
24+
</tr>
25+
</tbody>
26+
</table>
27+
28+
## Syntax
29+
30+
```http
31+
Cross-Origin-Embedder-Policy-Report-Only: <token>; <parameter>
32+
```
33+
34+
### Directives
35+
36+
The header should only be set with just one token and a `report-to` endpoint.
37+
38+
Setting the header more than once or with multiple tokens is equivalent to setting `unsafe-none`.
39+
Omitting `report-to` makes the header functionally inert.
40+
41+
The `<token>` value can be one of:
42+
43+
- `unsafe-none`
44+
- : Allows the document to load cross-origin resources requested in `no-cors` mode **without** giving explicit permission through the {{HTTPHeader("Cross-Origin-Resource-Policy")}} header.
45+
This is the default value.
46+
47+
- `require-corp`
48+
- : A document can only load resources requested in `no-cors` mode from the same origin, or resources that have explicitly set the {{HTTPHeader("Cross-Origin-Resource-Policy")}} header to a value that allows it to be embedded.
49+
50+
Cross-origin resource loading will be blocked by COEP unless:
51+
- The resource is requested in `no-cors` mode and the response includes a {{HTTPHeader("Cross-Origin-Resource-Policy")}} header that allows it to be loaded into the document origin.
52+
- The resource is requested in `cors` mode; for example, in HTML using the [`crossorigin`](/en-US/docs/Web/HTML/Reference/Attributes/crossorigin) attribute, or in JavaScript by making a request with [`{mode="cors"}`](/en-US/docs/Web/API/RequestInit#cors).
53+
Note that requests made in `cors` mode won't be blocked by COEP or trigger COEP violations, but must still be permitted by CORS.
54+
55+
- `credentialless`
56+
- : A document can load cross-origin resources that are requested in [`no-cors` mode](/en-US/docs/Web/API/Request/mode) **without** an explicit permission via the {{HTTPHeader("Cross-Origin-Resource-Policy")}} header.
57+
In this case requests are sent without credentials: cookies are omitted in the request, and ignored in the response.
58+
59+
The cross-origin loading behavior for other [request modes](/en-US/docs/Web/API/Request/mode#cors) is the same as for [`require-corp`](#require-corp).
60+
For example, a cross-origin resource requested in `cors` mode must support (and be permitted by) CORS.
61+
62+
The `<parameter>` is optional, and can be one of:
63+
64+
- `report-to <endpoint_name>` {{optional_inline}}
65+
- : The `<endpoint_name>` is the name of the endpoint to which policy violations will be sent.
66+
The mapping between the name and a particular endpoint is defined separately in the {{httpheader("Reporting-Endpoints")}} HTTP header.
67+
68+
## Specifications
69+
70+
{{Specifications}}
71+
72+
## Browser compatibility
73+
74+
{{Compat}}
75+
76+
## See also
77+
78+
- {{HTTPHeader("Cross-Origin-Embedder-Policy")}}
79+
- {{HTTPHeader("Cross-Origin-Opener-Policy")}}
80+
- {{domxref("Window.crossOriginIsolated")}} and {{domxref("WorkerGlobalScope.crossOriginIsolated")}}
81+
- {{domxref("ReportingObserver")}}
82+
- {{domxref("COEPViolationReport")}}
83+
- [Reporting API](/en-US/docs/Web/API/Reporting_API)
84+
- [Cross Origin Opener Policy](https://web.dev/articles/why-coop-coep#coep) in _Why you need "cross-origin isolated" for powerful features_ on web.dev (2020)
85+
- [COOP and COEP explained: Artur Janc, Charlie Reis, Anne van Kesteren](https://docs.google.com/document/d/1zDlfvfTJ_9e8Jdc8ehuV4zMEu9ySMCiTGMS9y0GU92k/edit?tab=t.0) (2020)

0 commit comments

Comments
 (0)