
// TL;DR
Tabnabbing is a clever evolution of phishing that exploits something you do without thinking: leaving tabs open. A background tab quietly rewrites itself into a fake login page, so when you return to it you assume your session expired and re-enter your credentials — straight to the attacker. The more technical variant, reverse tabnabbing, is a genuine web bug: any target=”_blank” link hands the page it opens a window.opener reference that lets it redirect your original tab. This piece explains both, why they happen, and the one-line fix (rel=”noopener”) that closes the hole.
What is tabnabbing?
Tabnabbing (also written tabnapping) is a phishing and social-engineering technique that persuades users to hand over their login credentials by impersonating a trusted website — but with a twist. Rather than deceiving you the instant you arrive, it manipulates a browser tab you’ve already opened and left inactive, swapping its content for a convincing fake while your attention is elsewhere.
It belongs to a broader class of web weaknesses involving unvalidated redirects and forwards, and it’s best understood as an advanced form of phishing — one that attacks your memory and assumptions rather than a single careless click.
Where the name comes from
The term was coined in 2010 by Aza Raskin, a well-known security researcher and interface designer, who described the technique publicly to raise awareness of it.
The word itself is a blend of “tab” and “kidnapping” (napping) — a fitting image, since the attack effectively hijacks one of your open tabs and turns it against you while you’re not looking.
The classic attack: hijacking an idle tab

The original form of the attack relies on inattention plus one simple technical fact: a page keeps running even when you’re not looking at it. JavaScript can detect that its own tab has lost focus, and it can rewrite the page while you’re away.
Conceptually it unfolds like this:
- You open a page and move on. You visit a site — perhaps from a link — and switch to another tab, leaving the first open and forgotten in the background.
- The idle tab rewrites itself. The page’s script notices it has lost focus (via events like
blur, or the Page Visibility API). After enough time, it swaps the document’s content — and even itstitleand favicon — to impersonate a service you trust, like your email or bank login. - You come back and misread the situation. Returning later, you see what looks like your email provider’s login screen and assume your session timed out. So you log in again.
- The credentials go to the attacker. The page that captured your details was never the real service. It often then forwards you to the genuine site, so nothing feels wrong.
The danger is the timing. By the time you interact with the fake page, you’ve lost track of where that tab came from.
Reverse tabnabbing: why window.opener is the real bug
There’s a second, more technical variant — reverse tabnabbing — and this is where tabnabbing stops being “just social engineering” and becomes an actual web vulnerability. It answers the question why does this happen in the first place?
When a page opens a new tab — whether through window.open() or a link with target="_blank" — the browser, by default, hands the newly opened page a reference back to the page that opened it, through the JavaScript property window.opener.
That reference is the problem. The new page (which may be attacker-controlled) can use window.opener to navigate the original tab to a different URL — even though the two pages are on completely different domains. The same-origin policy blocks the new page from reading the opener’s content, but it does not block it from redirecting the opener:
// Running on the attacker's page, opened via target="_blank"
if (window.opener) {
window.opener.location = "https://evil.example/fake-login";
}
So picture a trusted site — a forum, a webmail client — that links out to an external page with target="_blank". You click the link, the external page opens in a new tab, and you start reading it. Meanwhile, that page quietly redirects your original tab to a pixel-perfect fake of the trusted site’s login. When you switch back, you’re looking at what appears to be the site you were already on, now “logged out.” You log in — into the attacker’s page.
This is why the bug shows up constantly in security reviews of sites that link outward: any target="_blank" link to an untrusted destination hands that destination partial control of your tab.
The fix: noopener and noreferrer
The defect is that window.opener is populated by default. The fix is to sever that reference so the opened page gets window.opener === null and can’t touch the original tab.
For links, add rel="noopener":
<a href="https://external-site.example" target="_blank" rel="noopener">
Visit site
</a>
rel="noopener" ensures the new page has no handle on the opener. It’s common to pair it with noreferrer, which additionally strips the Referer header (and also implies noopener in older browsers):
<a href="https://external-site.example" target="_blank" rel="noopener noreferrer">
Visit site
</a>
For window.open() in script, pass noopener in the feature string:
window.open("https://external-site.example", "_blank", "noopener");
The good news: modern browsers now default target="_blank" links to noopener behaviour automatically. But that default is relatively recent, plenty of older pages and non-default code paths are still exposed, and relying on the browser isn’t a substitute for setting it explicitly. If you build sites, make rel="noopener" a habit on every outbound target="_blank" link.
Why it’s so effective
- It exploits trust in your own tabs. We scrutinise links before clicking, but rarely question a tab we opened ourselves minutes ago.
- It hides in plain sight. A matching title, favicon, and page design make the fake indistinguishable from the real login at a glance.
- It weaponises routine. “My session must have expired, let me log in again” is such a normal thought that it rarely triggers suspicion.
- The lure and the capture are separated in time, which defeats the usual instinct to be cautious “right after clicking something sketchy.”
How to protect yourself
- Check the URL before you log in — every time. The surest defence is to read the address bar. A fake page can copy everything except the real domain.
- Be wary of unexpected re-login prompts. If a tab suddenly asks you to log in again, don’t assume your session expired. Close it and navigate to the service fresh via a bookmark or by typing the address.
- Use a password manager. It fills credentials based on the true domain, so on a look-alike page it simply won’t offer to log you in — a quiet but reliable warning.
- Enable two-factor authentication. Even if credentials are captured, a second factor raises the bar significantly.
- Close tabs you’re done with. Fewer forgotten tabs means fewer opportunities for one to be turned against you.
And if you build websites, the responsibility shifts to you: add rel="noopener" (ideally noopener noreferrer) to every outbound target="_blank" link, and pass noopener to any window.open() call. It’s a one-line change that removes reverse tabnabbing entirely.
Thanks for reading — keep an eye on your tabs. Happy hacking!
Leave a Reply