Making your website "cross-origin isolated" using COOP and COEP

Updates
October 15th, 2020: self.crossOriginIsolated is available from Chrome 87.
Reflecting that, document.domain is immutable when self.crossOriginIsolated
returns true. performance.measureUserAgentSpecificMemory() is ending its origin trial and is

Some web APIs increase the risk of side-channel attacks like Spectre. To
mitigate that risk, browsers offer an opt-in-based isolated environment called
cross-origin isolated. With a cross-origin isolated state, the webpage will be
able to use privileged features including:

The cross-origin isolated state also prevents modifications of
document.domain. (Being able to alter document.domain allows communication
between same-site documents and has been considered a loophole in the
same-origin policy.)

To opt in to a cross-origin isolated state, you need to send the following
HTTP headers on the main document:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

These headers instruct the browser to block loading of resources or iframes
which haven’t opted into being loaded by cross-origin documents, and prevent
cross-origin windows from directly interacting with your document. This also
means those resources being loaded cross-origin require opt-ins.

You can determine whether a web page is in a cross-origin isolated state by
examining
self.crossOriginIsolated.

This article shows how to use these new headers. In a follow-up
article
I will provide more background and context.

This article is aimed at those who would like to get their websites ready for
using SharedArrayBuffer, WebAssembly Threads, performance.measureUserAgentSpecificMemory()
or the JS Self-Profiling API in a more robust manner across browser
platforms.

Key Term:
This article uses many similar-sounding terminologies. To make things
clearer, let’s define them first:

Deploy COOP and COEP to make your website cross-origin isolated

Integrate COOP and COEP

1. Set the Cross-Origin-Opener-Policy: same-origin header on the top-level document

By enabling COOP on a top-level document, windows
with the same origin, and windows opened from the document, will have a separate
browsing context group unless they are in the same origin with the same COOP
setting. Thus, isolation is enforced for opened windows.

A browsing context group is a group of tabs, windows or iframes which share the
same context. For example, if a website (https://a.example) opens a popup
window (https://b.example), the opener window and the popup window share the
same browsing context and they have access to each other via DOM APIs such as
window.opener.

Browsing Context Group

As of Chrome 83, dedicated DevTools support is not yet available for COOP.
However, you can examine window.opener === null from the opened window, or
openedWindow.closed === true from the opener window to determine if they are
in separate browsing context groups.

2. Ensure resources have CORP or CORS enabled

Make sure that all resources in the page are loaded with CORP or CORS
HTTP headers. This step
is required for step four, enabling COEP.

Here is what you need to do depending on the nature of the resource:

  • If the resource is expected to be loaded only from the same origin, set
    the Cross-Origin-Resource-Policy: same-origin header.
  • If the resource is expected to be loaded only from the same site but cross
    origin
    , set the Cross-Origin-Resource-Policy: same-site header.
  • If the resource is loaded from cross origin(s) under your control, set the
    Cross-Origin-Resource-Policy: cross-origin header if possible.
  • For cross origin resources that you have no control over:
    • Use the crossorigin attribute in the loading HTML tag if the resource is
      served with CORS.
    • Ask the owner of the resource to support either CORS or CORP.
  • For iframes, use CORP and COEP headers as follows:
    Cross-Origin-Resource-Policy: same-origin (or same-site, cross-origin
    depending on the context) and Cross-Origin-Embedder-Policy: require-corp.

Key Term:
It’s important that you understand the difference between "same-site" and
"same-origin". Learn about the difference at Understanding same-site and
same-origin
.

3. Use the COEP Report-Only HTTP header to assess embedded resources

Before fully enabling COEP, you can do a dry run by using the
Cross-Origin-Embedder-Policy-Report-Only header to examine whether the policy
actually works. You will receive reports without blocking embedded content.
Recursively apply this to all documents. For information on the Report-Only HTTP
header, see Observe issues using the Reporting
API
.

4. Enable COEP

Once you’ve confirmed that everything works, and that all resources can be
successfully loaded, apply the Cross-Origin-Embedder-Policy: require-corp HTTP
header to all documents including those that are embedded via iframes.

Squoosh (an image optimization PWA) now uses COOP /
COEP

to gain access to Wasm Threads (and Shared Array Buffer) as well on Android
Chrome.

Determine whether isolation succeeded with self.crossOriginIsolated

The self.crossOriginIsolated property returns true when the web page is in a
cross-origin isolated state and all resources and windows are isolated within
the same browsing context group. You can use this API to determine whether you
have successfully isolated the browsing context group and gained access to
powerful features like performance.measureUserAgentSpecificMemory().

Caution:
The
self.crossOriginIsolated
property is available in Chrome from version 87.

Debug issues using Chrome DevTools

For resources that are rendered on the screen such as images, it’s fairly easy
to detect COEP issues because the request will be blocked and the page will
indicate a missing image. However, for resources that don’t
necessarily have a visual impact, such as scripts or styles, COEP issues might
go unnoticed. For those, use the DevTools Network panel. If
there’s an issue with COEP, you should see
(blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) in the Status
column.

COEP issues in the Status column of the Network panel.

You can then click the entry to see more details.

Details of the COEP issue are shown in the Headers tab after clicking a network resource in the Network panel.

While COEP debugging is already available, COOP debugging in Chrome
DevTools is still being worked
on
.

Observe issues using the Reporting API

The Reporting
API
is another
mechanism through which you can detect various issues. You can configure the
Reporting API to instruct your users’ browser to send a report whenever COEP
blocks the loading of a resource or COOP isolates a popup window. Chrome has
supported the
Report-To
header since version 69 for a variety of uses including COEP and COOP.

The Reporting API is undergoing transition to a new
version. Chrome is planning to release it
soon, but will leave the older API in place for some time.
Firefox is also considering the new
API
. You may want to use
both APIs during the transition.

Enable the Reporting API

You can try the COOP Reporting API in Chrome 86 and later by doing one of the following:

  1. Enabling Chrome flags
  2. Registering for an origin trial
Enable via Chrome flags
  1. Go to chrome://flags
  2. Enable Cross Origin Opener Policy reporting (chrome://flags/#cross-origin-opener-policy-reporting)
  3. Enable Cross Origin Opener Policy access reporting
    (chrome://flags/#cross-origin-opener-policy-access-reporting)
Register for an origin trial

Origin trials allow you to try new features and give feedback on their
usability, practicality, and effectiveness to the web standards community. For
more information, see the Origin Trials Guide for Web Developers.
To sign up for this or another origin trial, visit the registration page.

  1. Request a token for your origin.
  2. Add the token to your pages. There are two ways to do that:
    • Add an origin-trial <meta> tag to the head of each page. For example,
      this may look something like:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • If you can configure your server, you can also add the token
      using an Origin-Trial HTTP header. The resulting response header should
      look something like:
      Origin-Trial: TOKEN_GOES_HERE

Caution:
To use COOP Reporting API, the token must be served as an HTTP header instead of
a <meta> tag.

Report-To

To specify where the browser should send reports, append the Report-To HTTP
header to any document that is served with a COEP or COOP HTTP header. The
Report-To header also supports a few extra parameters to configure the
reports. For example:

Report-To: { group: 'coep_report', max_age: 86400, endpoints: [{ url: 'https://first-party-test.glitch.me/report'}]},{ group: 'coop_report', max_age: 86400, endpoints: [{ url: 'https://first-party-test.glitch.me/report'}]}

The parameters object has three properties:

group

The group property names your various reporting endpoints. Use these names to
direct a subset of your reports. For instance, in the
Cross-Origin-Embedder-Policy and Cross-Origin-Opener-Policy directives you
can specify the relevant endpoint by providing the group name to report-to=.
For example:

Cross-Origin-Embedder-Policy: require-corp; report-to="coep_report"
Cross-Origin-Opener-Policy: same-origin; report-to="coop_report"

When the browser encounters this, it will cross reference the report-to value
with the group property on the Report-To header to look up the endpoint.
This example cross references coep_report and coop_report to find the
endpoint https://first-party-test.glitch.me/report.

If you prefer to receive reports without blocking any embedded content or
without isolating a popup window, append -Report-Only to respective headers:
i.e. Cross-Origin-Embedder-Policy-Report-Only and
Cross-Origin-Opener-Policy-Report-Only. For example:

Cross-Origin-Embedder-Policy-Report-Only: require-corp; report-to="coep_report"
Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop_report"

By doing this, when the browser detects cross origin resources that don’t have
CORP or CORS, it sends a report using the Reporting API without actually
blocking those resources because of COEP.

Similarly, when the browser opens a cross-origin popup window, it sends a report
without actually isolating the window because of COOP. It also reports when
different browsing context groups try to access each other, but only in
"report-only" mode.

max_age

The max_age property specifies the time in seconds after which unsent reports
are to be dropped. The browser doesn’t send the reports right away.
Instead, it transmits them out-of-band whenever there aren’t any other higher
priority tasks. The max_age prevents the browser from sending reports that are
too stale to be useful. For example, max_age: 86400 means that reports older
than twenty-four hours will not be sent.

endpoints

The endpoints property specifies the URLs of one or more reporting endpoints.
The endpoint must accept CORS if it’s hosted on a different origin. The browser
will send reports with a Content-Type of application/reports+json.

An example COEP report payload when cross-origin resource is blocked looks like
this:

[{
"age": 25101,
"body": {
"blocked-url": "https://third-party-test.glitch.me/check.svg?",
"blockedURL": "https://third-party-test.glitch.me/check.svg?",
"destination": "image",
"disposition": "enforce",
"type": "corp"
},
"type": "coep",
"url": "https://first-party-test.glitch.me/?coep=require-corp&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]

Caution:
blocked-url is there for backward compatibility only and will be removed
eventually
.

An example COOP report payload when a popup window is opened isolated looks like
this:

[{
"age": 7,
"body": {
"disposition": "enforce",
"effectivePolicy": "same-origin",
"nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
"type": "navigation-from-response"
},
"type": "coop",
"url": "https://first-party-test.glitch.me/coop?coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

When different browsing context groups try to access each other (only on
"report-only" mode), COOP also sends a report. For example, a report when
postMessage() is attempted would look like this:

[{
"age": 51785,
"body": {
"columnNumber": 18,
"disposition": "reporting",
"effectivePolicy": "same-origin",
"lineNumber": 83,
"property": "postMessage",
"sourceFile": "https://first-party-test.glitch.me/popup.js",
"type": "access-from-coop-page-to-openee"
},
"type": "coop",
"url": "https://first-party-test.glitch.me/coop?report-only&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
"age": 51785,
"body": {
"disposition": "reporting",
"effectivePolicy": "same-origin",
"property": "postMessage",
"type": "access-to-coop-page-from-openee"
},
"type": "coop",
"url": "https://first-party-test.glitch.me/coop?report-only&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

Conclusion

Use a combination of COOP and COEP HTTP headers to opt a web page into a special
cross-origin isolated state. You will be able to examine
self.crossOriginIsolated to determine whether a web page is in a
cross-origin isolated state.

In upcoming releases of Chrome, this cross-origin isolated state will prevent
altering
document.domain

and will give access to powerful features such as:

We’ll keep this post updated as new features are made available to this
cross-origin isolated state, and further improvements are made to DevTools
around COOP and COEP.


Print Share Comment Cite Upload Translate
APA
Eiji Kitamura | Sciencx (2024-03-28T17:05:15+00:00) » Making your website "cross-origin isolated" using COOP and COEP. Retrieved from https://www.scien.cx/2020/04/13/making-your-website-cross-origin-isolated-using-coop-and-coep/.
MLA
" » Making your website "cross-origin isolated" using COOP and COEP." Eiji Kitamura | Sciencx - Monday April 13, 2020, https://www.scien.cx/2020/04/13/making-your-website-cross-origin-isolated-using-coop-and-coep/
HARVARD
Eiji Kitamura | Sciencx Monday April 13, 2020 » Making your website "cross-origin isolated" using COOP and COEP., viewed 2024-03-28T17:05:15+00:00,<https://www.scien.cx/2020/04/13/making-your-website-cross-origin-isolated-using-coop-and-coep/>
VANCOUVER
Eiji Kitamura | Sciencx - » Making your website "cross-origin isolated" using COOP and COEP. [Internet]. [Accessed 2024-03-28T17:05:15+00:00]. Available from: https://www.scien.cx/2020/04/13/making-your-website-cross-origin-isolated-using-coop-and-coep/
CHICAGO
" » Making your website "cross-origin isolated" using COOP and COEP." Eiji Kitamura | Sciencx - Accessed 2024-03-28T17:05:15+00:00. https://www.scien.cx/2020/04/13/making-your-website-cross-origin-isolated-using-coop-and-coep/
IEEE
" » Making your website "cross-origin isolated" using COOP and COEP." Eiji Kitamura | Sciencx [Online]. Available: https://www.scien.cx/2020/04/13/making-your-website-cross-origin-isolated-using-coop-and-coep/. [Accessed: 2024-03-28T17:05:15+00:00]
rf:citation
» Making your website "cross-origin isolated" using COOP and COEP | Eiji Kitamura | Sciencx | https://www.scien.cx/2020/04/13/making-your-website-cross-origin-isolated-using-coop-and-coep/ | 2024-03-28T17:05:15+00:00
https://github.com/addpipe/simple-recorderjs-demo