The fix, in one snippet
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.
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
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 GoogleSigning in is free and takes one click. We store your email address and nothing else.