Safeguard
Application Security•

CWE-1022 window.opener Tabnabbing: Cause and Fix

Links with target blank can let the opened page redirect the original tab. CWE-1022 explained, with rel noopener fixes for HTML and JavaScript.

Safeguard Security Team
6 min read

A link that opens in a new tab looks harmless. You click, a new page appears, you read it, you close it and go back. But the page you left may have been quietly changed while you were reading.

CWE-1022 is the weakness where a web application produces links to untrusted external sites but does not prevent the external site from modifying security critical properties of the window.opener object, such as the location property. MITRE lists it as a Variant, with JavaScript and web based platforms.

It applies to anything that renders links to content you do not control: user generated content, comments, profile pages, documentation sites, library and CMS software.

How it happens

When a link uses target="_blank", the browser opens the target in a new window or tab. Historically that new page received a reference back to the page that opened it, through window.opener.

MITRE's description spells out the risk. The window.opener object records information about the original page that offered the link. If an attacker can run script on the target page, they can read or modify certain properties of the window.opener object, including location, even when the two pages are not the same origin.

So the attacker's page can do this:

// Running on the attacker's page, opened from your site
if (window.opener) {
  window.opener.location = "https://login.example.invalid/phish";
}

The user is looking at the new tab. The redirect happens in the original tab, which is not in view. When they switch back, they see what looks like your site asking them to sign in again. MITRE notes that the user might not notice the suspicious redirection, since the browser is focusing the display on the target page.

This pattern is often called reverse tabnabbing. The vulnerable markup is ordinary:

<!-- Vulnerable: untrusted target, no protection -->
<a href="https://user-supplied.example.com" target="_blank">Visit the site</a>

The observed example on the MITRE page is CVE-2022-4927: library software that does not use the rel: "noopener noreferrer" setting, allowing tabnabbing attacks that redirect to a malicious page.

What an attacker gains

MITRE lists a modest but real set of consequences:

  • Confidentiality impact. The user may be redirected to an untrusted page that contains undesired content or malicious script code.
  • Altered execution logic. The original tab's behavior changes without any action from the user.

In practice this is a phishing enabler. The attacker does not need to break your session. They rely on the user trusting the tab that carries your name and address, or a look alike of it. Pages that display links from users or third parties give attackers the foothold they need, since the attacker can put a link on your page that goes to their page.

How to find it

MITRE lists automated static analysis, SAST, as a way to find some instances. Templates and components that emit target="_blank" are easy for a scanner to pick out.

You can also do a quick check yourself:

  1. Search your templates, components and content for target="_blank" and for window.open(.
  2. For each, ask whether the destination can be influenced by a user or comes from content you do not control.
  3. Check that every such link includes rel="noopener noreferrer".
  4. Look at rich text editors and markdown renderers. They often produce external links automatically, and their output is a common gap.
  5. In the browser, open an external link from your site, then open the console in the new tab and type window.opener. If it returns an object instead of null, the protection is missing.

How to fix it

MITRE lists three mitigations.

  1. Design for it. Specify in the design that any linked external document must not be granted access to the location object of the calling page.
  2. Use rel noopener noreferrer. When creating a link with an a tag and a defined target such as _blank or a named frame, give it the rel attribute value noopener noreferrer. When opening the external document in a new window through JavaScript, reset the opener by setting it equal to null.
  3. Avoid _blank targets. MITRE notes this can affect usability, so it is the blunt option.

The fixed markup:

<a href="https://user-supplied.example.com" target="_blank" rel="noopener noreferrer">Visit the site</a>

And the JavaScript form:

const w = window.open("https://user-supplied.example.com", "_blank");
if (w) {
  w.opener = null;
}

A few extras for real projects:

  • Apply the rule in one component, such as a shared link component, rather than at every call site.
  • Add a lint rule that flags target="_blank" without a matching rel value. It is a cheap check that stops regressions.
  • For user generated content, post process rendered HTML to add the rel attribute to every external link.
  • Review library code. The CVE example shows the problem can sit inside software you depend on, not just code you wrote.

Try it yourself

This demo shows a static code scan flagging risky patterns in source, the same kind of scan that can flag unprotected link targets.

Click through it at your own pace, or open it full screen.

Because the CVE example involves a library, it is worth checking your dependencies too. The free in-browser scan at gold.safeguard.sh/scan needs no login, keeps the file on your machine and handles up to 100 dependencies. Reachability analysis can then tell you whether your code actually calls the affected function.

Quick check

What does the attacker's page change in the original tab?

It can modify the location property of window.opener, redirecting the original tab to a malicious page while the user is looking at the new tab.

Which rel value does MITRE recommend for links with a target?

noopener noreferrer. For windows opened from JavaScript, set the opener equal to null.

Why is user generated content a particular concern?

It lets someone outside your control place a link on your page. If that link opens a page the attacker controls without protection, the attacker can reach back into your page's tab.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.