Cross-Origin-Opener-Policy

The page does not set Cross-Origin-Opener-Policy, so windows it opens, or that open it, from other origins keep a reference to it and share its browsing context group.

Do this: Send Cross-Origin-Opener-Policy: same-origin. A window you open, or that opens you, keeps a handle on your page and can probe it across origins.
PassCross-Origin-Opener-Policy isolates the page from cross-origin windows.
LowCross-Origin-Opener-Policy is missing or set to unsafe-none.

The fix, in one snippet

Example to adapt Any server
Cross-Origin-Opener-Policy: same-origin

Illustrative values. Change the paths, hostnames and options to match your own site before using it.

The sections below explain what is tested, why it matters and the alternatives.

What we test

Scan.now reads the Cross-Origin-Opener-Policy header on the response to /. The values same-origin and same-origin-allow-popups pass; noopener-allow-popups, a newer value, also passes. The check reports low severity when the header is absent or set to unsafe-none, which is the browser default. It additionally notes whether Cross-Origin-Embedder-Policy is present, because the pair COOP: same-origin plus COEP: require-corp puts the page into the cross-origin-isolated state that unlocks SharedArrayBuffer and high-resolution timers. A related header for resources rather than windows is covered by cross-origin-resource-policy.

Why it matters

When your page opens another site with window.open, or is opened by one, both windows share a browsing context group. The opener keeps a window.opener handle and can navigate your tab to a phishing page while the user is looking elsewhere (reverse tabnabbing), can count your frames, and in some browser architectures shares an operating-system process with you, which is what Spectre-style side channels need. Browsers have defaulted target="_blank" links to noopener since 2021, which closes the most common route, but scripted window.open calls, older browsers and pages that other sites open remain exposed. COOP: same-origin severs the relationship: cross-origin openers get a null handle and your document is placed in its own group. This is defence-in-depth rather than a direct hole, hence low severity. Background is in the security headers guide.

How to fix it

Add the header to HTML responses. nginx:

add_header Cross-Origin-Opener-Policy "same-origin" always;

Apache:

Header always set Cross-Origin-Opener-Policy "same-origin"

Express with Helmet sets same-origin by default from version 5; to set it explicitly:

app.use(helmet.crossOriginOpenerPolicy({ policy: 'same-origin' }));

Cloudflare: add it with a Transform Rule that sets a static response header. Test after deploying: if your site uses OAuth or payment popups that call back into the opener (window.opener.postMessage), same-origin breaks them. Use same-origin-allow-popups in that case, which isolates your page from cross-origin openers while letting popups you open keep their reference. If you want full cross-origin isolation for WebAssembly threads or precise timers, pair it with Cross-Origin-Embedder-Policy: require-corp and make sure every cross-origin subresource sends CORP or CORS headers first, or those resources will stop loading.

Where this fits

Cross-Origin-Opener-Policy is check 5 of 13 that the website vulnerability scanner runs under http security headers, ordered the way they are worth fixing. That ordering is the point: Fixing this one while the check above it still fails buys less than it looks like.

Fix this one first

Above it in the same category sits Content-Security-Policy missing (medium), where the page is served without an enforced Content-Security-Policy. An attacker who has that does not need this, so it is the better use of the same hour.

What fixing this still leaves open

Cross-Origin-Opener-Policy closes one route in. Immediately below it: Permissions-Policy, where no Permissions-Policy header restricts powerful browser features; Referrer-Policy, where no Referrer-Policy is set, or it is set to a value that sends full URLs to other sites; Server version disclosure, where the Server header reveals the exact web server software and version, such as Apache/2.4.58 (Ubuntu) or nginx/1.24.0, which lets attackers and bots match it to known vulnerabilities without any probing.

Found in the same scan

The website vulnerability scanner reports this alongside checks from other categories that are at least as serious, including Certificate chain and hostname validation, where the certificate presented for this hostname did not validate: The chain does not reach a trusted root, an intermediate is missing, the name does not match, or the certificate is self-signed or expired, and Exposed .env configuration file, where a .env configuration file is served from the web root. A single run of website vulnerability scanner answers all of them at once.

Prompt for an AI Hand this check to an assistant Sign in to copy it
The first few lines
You are a senior web engineer. I ran a security and SEO scanner against my site and it reported the finding below. Fix it properly rather than suppressing the symptom.

Finding: Cross-Origin-Opener-Policy (low severity)
Scanner check id: cross-origin-opener-policy
17 more lines, including the evidence and the exact fix

The rest of this prompt names the pages and line numbers we found the problem on, the configuration to change, and the constraints a good answer has to respect. It is free, it just needs an account so the work is not scraped wholesale.

Sign in with Google

Signing in is free and takes one click. We store your email address and nothing else.

References

  1. MDN: Cross-Origin-Opener-Policy
  2. web.dev: Why you need cross-origin isolation
  3. HTML Standard: Cross-origin opener policies

Related guides