Lion Cipher Lab
Exploit and fix reverse tabnabbing
- AppSec / DevSecOps
- Intermediate
- ~45 min
- Free · no account required
Why it matters
Reverse tabnabbing is a quiet, high-trust phishing move. A site you trust (a forum, a docs page, a company intranet) links out to something it does not fully control — a user-submitted post, a partner page, an ad — and opens it in a new tab. If that link does not cut the back-channel, the page that just opened receives a live window.opener handle pointing at the tab you came from. While you read the new tab, the opened page sets window.opener.location to a look-alike login page. You switch back to the original tab, see what looks like the site you trusted asking you to 'log in again,' and…
What you'll learn
- explaining reverse tabnabbing: a page that opens an untrusted link with target="_blank" or window.open WITHOUT cutting the back-channel hands the opened page a live window.opener handle to the original tab
- defining window.opener precisely — the handle a newly opened page gets back to the page that opened it — and seeing that an attacker uses opener.location to navigate YOUR original tab somewhere else
- defining an ORIGIN as scheme + host + port and seeing that localhost:8000 (trusted site) and localhost:9000 (attacker) are DIFFERENT origins, i.e. a real cross-origin open
- building a tiny vulnerable 'trusted' site that opens a community post with window.open(url) and no noopener, serving it locally with Python's http.server
- building a malicious destination page that reads window.opener and silently redirects the ORIGINAL tab to a phishing clone, and watching it happen in a real browser
- fixing it the modern way: rel="noopener noreferrer" on anchors and the 'noopener' windowFeatures argument to window.open, set on the LINKING page
- reloading the attack and confirming window.opener is now null so the original tab can no longer be navigated
- knowing the judgment: noopener is NOT noreferrer (noreferrer also drops the Referer header); CSP does not fix this; the fix lives on the linking page not the destination; and modern browsers default anchor target=_blank to noopener, so this is now mostly a window.open and old-browser concern
Steps in this lab
- The vocabulary: new tabs, window.opener, and reverse tabnabbing
- Set up: confirm Python, make the folders
- Build the VULNERABLE trusted site (opens a link without cutting the opener)
- Build the attacker's pages — the opener hijack and the phishing clone
- Run the exploit and watch your original tab get hijacked
- Fix it: noopener on the LINKING page (anchor rel and window.open option)
- Reload the attack and confirm the handle is gone
- Judgment: where this really bites, and what does NOT fix it
- What you did — and the reflex to keep