Cross-Origin-Opener-Policy: isolating your browsing context
Cross-Origin-Opener-Policy decides whether a document shares a browsing context group with the pages that open it or that it opens, which is what cuts the window.opener reference.
At a glance
- Direction
- Response only, on a top level document. It is ignored on framed documents.
- Defined in
- The HTML standard (WHATWG)
- When absent
- unsafe-none. Your page keeps a live window reference to and from cross-origin pages.
- Values
- unsafe-none (default), same-origin-allow-popups, same-origin
- Required for
- Cross-origin isolation, together with Cross-Origin-Embedder-Policy
- Visible effect
- window.opener becomes null across the boundary, and named window targeting stops working.
- In the headers checker
- Shown in the raw response header table. It is not one of the graded headers.
In detail
When a page opens another window, both keep references to each other by default. That link is how a page you opened can navigate you somewhere else after the fact, the behaviour behind tabnabbing. Setting same-origin puts your document in its own browsing context group unless the other side is same-origin with the same policy, and the reference on both sides becomes null.
The same-origin-allow-popups value exists for the common case where a page opens an authentication or payment window that has to talk back. Your document stays isolated from whatever opened it, while windows it opens itself keep their reference. Choose it when you are the opener in a flow that depends on a message being posted back to you.
The strictest value is a prerequisite for cross-origin isolation. A document only becomes cross-origin isolated, gaining SharedArrayBuffer and high resolution timers, when it sends this header as same-origin and Cross-Origin-Embedder-Policy as require-corp together. One without the other leaves the capability off, which is the usual reason a working local prototype loses SharedArrayBuffer in production.
Because the effect only exists between top level documents, adding the header to an iframe response changes nothing. It also applies only to the document carrying it, so a login page with the header and an application shell without it are isolated differently, which shows up as an intermittently null opener depending on the entry point.
Examples
Cross-Origin-Opener-Policy: same-originCross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corpCheck the result in the page itself: self.crossOriginIsolated is true only when both are in force and every subresource cooperates.
Cross-Origin-Opener-Policy: same-origin-allow-popupsThings that catch people out
- Third party sign-on and payment flows that post a message back to the opener break under same-origin. Use same-origin-allow-popups on the page that starts the flow.
- The header does nothing on a framed document, so testing it inside an iframe produces a confusing null result.
- Setting this header without Cross-Origin-Embedder-Policy does not enable cross-origin isolation, and the reverse is equally true. Both are required.
Try it: HTTP Headers Checker
Check a live URL or paste headers you already have. It grades six security headers from A+ to F and lists every other header the response returned.
HTTP Headers Checker
LOCAL · Browser-OnlyView HTTP response headers for any URL
Enter any website URL to fetch and analyze its HTTP response headers. We'll automatically add https:// if needed.
Why Check Security Headers?
Security headers protect your website against common attacks like XSS, clickjacking, and MIME sniffing. They're set by your web server and cost nothing to implement. Missing security headers are one of the most common findings in security audits.
Related HTTP headers
All http headers →Cross-Origin-Embedder-Policy: require-corp and credentialless
What require-corp demands from every subresource, how credentialless relaxes it, and why enabling COEP is what breaks third party images and embeds.
Cross-Origin-Resource-Policy: who may embed this response
How CORP lets a response refuse to be embedded by other sites, how same-site differs from same-origin, and why asset hosts have to send cross-origin.
X-Frame-Options: DENY, SAMEORIGIN and clickjacking
What DENY and SAMEORIGIN do, why ALLOW-FROM never worked, and how CSP frame-ancestors supersedes this header while it is still worth sending.
Timing-Allow-Origin: exposing detailed resource timings
Why cross-origin resources show zeroed timings, what Timing-Allow-Origin unlocks in the Resource Timing API, and how it differs from a CORS allow header.
Clear-Site-Data: wiping browser state on logout
How Clear-Site-Data clears cookies, storage and caches for your origin, which directives are safe on a logout response, and where support is uneven.
Reporting-Endpoints: where browser reports are sent
How Reporting-Endpoints names collectors for CSP violations and deprecation warnings, how it differs from the older Report-To header, and what arrives.
Tools for this
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body