Making your website "cross-origin isolated" using COOP and COEP (original) (raw)

Use COOP and COEP to set up a cross-origin isolated environment and enable powerful features like SharedArrayBuffer, performance.measureUserAgentSpecificMemory() and high resolution timer with better precision.

Eiji Kitamura

Updates

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 ofdocument.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 examiningself.crossOriginIsolated.

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

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

Integrate COOP and COEP

By enabling COOP: same-origin 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 and mutual communication between both windows is disabled.

A browsing context group is a set of windows that can reference each other. For example, a top-level document and its child documents embedded via <iframe>. 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, therefore they have access to each other via DOM APIs such as window.opener.

Browsing Context Group

You can check if the window opener and its openee are in separate browsing context groups from DevTools.

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:

Before fully enabling COEP, you can do a dry run by using theCross-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 including the top-level document, iframes and worker scripts. For information on the Report-Only HTTP header, seeObserve issues using the Reporting API.

4. Enable COEP

Once you've confirmed that everything works, and that all resources can be successfully loaded, switch the Cross-Origin-Embedder-Policy-Report-Onlyheader to the Cross-Origin-Embedder-Policy header with the same value to all documents including those that are embedded via iframes and worker scripts.

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().

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 Statuscolumn.

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.

You can also determine the status of iframes and popup windows through theApplication panel. Go to the "Frames" section on the left hand side and expand "top" to see the breakdown of the resource structure.

You can check the iframe's status such as availability of SharedArrayBuffer, etc.

Chrome DevTools iframe inspector

You can also check the popup windows's status such as whether it's cross-origin isolated.

Chrome DevTools popup window inspector

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 pop-up window. Chrome has supported the Reporting API since version 69 for a variety of uses including COEP and COOP.

To learn how to configure the Reporting API and set up a server to receive reports, head over to Using the Reporting API.

Example COEP report

An example COEP reportpayload 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://cross-origin-isolation.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"
}]

Example COOP report

An example COOP report payload when a pop-up 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://cross-origin-isolation.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 whenpostMessage() is attempted would look like this:

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.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://cross-origin-isolation.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 examineself.crossOriginIsolated to determine whether a web page is in a cross-origin isolated state.

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.

Resources