Secure Your External Links: Prevent Tabnabbing and Privacy Leaks
- Amanda Foster
- 4 days ago
- 3 min read

When you add target="_blank" to external links, you might be creating security vulnerabilities and exposing user privacy. Here's how to fix it and test your site in just a few minutes.
The Problem
External links that open in new tabs create two critical issues:
1. Tabnabbing Attacks: The new page gets access to window.opener, allowing malicious sites to manipulate your original page or redirect users to convincing phishing sites.
2. Privacy Leaks: External sites receive detailed referrer information, potentially exposing search queries, session data, and sensitive browsing patterns.
The Simple Fix: How to Prevent Tabnabbing and Privacy Leaks
Use the code below to prevent tabnabbing and privacy leaks:
Add rel="noopener noreferrer" to all external links with target="_blank":
<!-- UNSAFE -->
<a href="https://external-site.com" target="_blank">External Link</a>
<!-- SAFE -->
<a href="https://external-site.com" target="_blank" rel="noopener noreferrer">External Link</a>
noopener: Prevents access to your original window
noreferrer: Blocks referrer information from being sent
Implementation Examples
HTML:
<a href="https://external-database.com" target="_blank" rel="noopener noreferrer">
View External Resource
</a>
Rails ERB:
<%= link_to "External Site", external_url, target: "_blank", rel: "noopener noreferrer" %>
JavaScript:
const link = document.createElement('a');
link.href = 'https://external-site.com';
link.target = '_blank';
link.rel = 'noopener noreferrer';
Test Your Site Right Now
Quick Console Audit
Run this JavaScript in your browser's console to audit all external links on any page:
// Audit external links on current page
function auditExternalLinks() {
const links = document.querySelectorAll('a[target="_blank"]');
let report = 'EXTERNAL LINKS SECURITY AUDIT:\n\n';
links.forEach((link, i) => {
const href = link.href;
const rel = link.getAttribute('rel') || 'none';
const isExternal = href.match(/^https?:\/\//) &&
!href.includes(window.location.hostname);
if (isExternal) {
const hasNoopener = rel.includes('noopener');
const hasNoreferrer = rel.includes('noreferrer');
const status = (hasNoopener && hasNoreferrer) ? '✅ SECURE' : '❌ VULNERABLE';
report += `${i+1}. ${href}\n`;
report += ` rel="${rel}"\n`;
report += ` Status: ${status}\n\n`;
}
});
console.log(report || 'No external links found');
}
auditExternalLinks();
Manual Testing
Test for window.opener vulnerability:
Click an external link with target="_blank"
In the new tab, open Developer Tools (F12)
In the console, type: window.opener
Secure result: null
Vulnerable result: Window {parent: Window, ...}
Test for referrer leaks:
Open Developer Tools → Network tab
Click an external link
Find the request to the external domain
Check Headers → Request Headers for Referer:
Secure: No referrer header present
Vulnerable: Shows your site's URL and potentially sensitive paths
Why This Matters
This is especially critical for:
Library systems: Research queries shouldn't be exposed to external databases
Healthcare portals: Patient information must stay confidential
Financial applications: Account activity requires protection
E-commerce sites: Shopping behavior should remain private
Quick Security Checklist
[ ] All external links with target="_blank" include rel="noopener noreferrer"
[ ] JavaScript-generated external links include security attributes
[ ] Testing confirms window.opener is null in new tabs
[ ] Testing confirms no referrer information leaks
Note on Internal Links
You only need these attributes on external links. Internal navigation within your domain is safe:
<!-- Internal links - no attributes needed -->
<a href="/internal-page" target="_blank">Internal Link</a>
<!-- External links - security attributes required -->
<a href="https://external-site.com" target="_blank" rel="noopener noreferrer">External</a>
Conclusion
Adding rel="noopener noreferrer" to external links is a simple fix that prevents serious security vulnerabilities and privacy breaches. Use the console audit script above to test your site today, and make this part of your standard development workflow.
The few minutes spent implementing this protection could save you from significant security incidents down the road.
