Tabnabbing Attack 101
Introduction
Did you know that the 'noreferrer' attributes play a pivotal role in web security? In this blog, we'll delve into the 'noreferrer' attributes, explaining their significance in protecting privacy and preventing tabnabbing attacks.
What is Tabnabbing?
Tabnabbing is a type of phishing attack that exploits the trust users have in the tabs they've opened in their browser. The attack works when a user clicks a link that opens a new tab, and then the malicious page gains control of the original tab through the window.opener property.
Here's how it typically works:
- User is on a legitimate website (let's say
trusted-site.com) - User clicks a link that opens in a new tab (attacker's site)
- The attacker's page uses JavaScript to redirect the original tab to a fake login page
- User switches back to what they think is the original tab
- User sees a fake login page and enters their credentials
- Attacker steals the credentials
The window.opener Property
When you open a link using target="_blank", the new page gets access to the window.opener property, which references the original page's window object. This allows the new page to navigate the original tab:
```javascript // On the malicious page if (window.opener) { window.opener.location = 'https://fake-login.com'; } ```
This is a significant security vulnerability!
The Solution: rel="noreferrer noopener"
To prevent tabnabbing attacks, you should always add rel="noopener noreferrer" to links that open in new tabs:
```html
Visit External Site Visit External Site \`\`\`Understanding the Attributes
noopener: Prevents the new page from accessing thewindow.openerpropertynoreferrer: Prevents the browser from sending the referrer header to the destination site (additional privacy benefit)
Real-World Example
Here's a complete example showing both vulnerable and secure implementations:
```javascript // Vulnerable Component function VulnerableLink() { return ( Click me ); }
// Secure Component function SecureLink() { return ( Click me ); } ```
Modern Browser Behavior
Good news! Modern browsers (Chrome 88+, Firefox 79+, Safari 12.2+) now automatically apply noopener behavior to target="_blank" links, even if you don't explicitly add the attribute. However, it's still a best practice to include it for:
- Backward compatibility with older browsers
- Explicit security documentation in your code
- The additional privacy benefit of
noreferrer
Impact on Analytics
One thing to note: using noreferrer means the destination site won't see where the traffic came from in their analytics. If you're linking to your own properties and want to track referrals, you might want to use only noopener:
```html
Visit Our Other Site \`\`\`Checking Your Site
You can use browser developer tools to check if your links are properly secured:
```javascript // Run this in console to find vulnerable links document.querySelectorAll('a[target="_blank"]').forEach(link => { const rel = link.getAttribute('rel') || ''; if (!rel.includes('noopener')) { console.warn('Vulnerable link found:', link.href); } }); ```
Best Practices
- Always use
rel="noopener noreferrer"for external links that open in new tabs - Use automated linting tools to catch missing attributes
- Consider using a Link component wrapper in React/Vue applications
- Educate your team about this security issue
React Example with Custom Hook
Here's a reusable solution for React applications:
```typescript import { AnchorHTMLAttributes } from 'react';
interface ExternalLinkProps extends AnchorHTMLAttributes
export function ExternalLink({ href, children, ...props }: ExternalLinkProps) { return ( <a href={href} target="_blank" rel="noopener noreferrer" {...props} > {children} ); }
// Usage
Conclusion
Tabnabbing attacks are a real threat that can be easily prevented by understanding and properly using the rel attribute. While modern browsers provide some automatic protection, it's important to be proactive about security.
Remember: Always add rel="noopener noreferrer" to links with target="_blank". It's a simple change that can prevent serious security issues.
Stay secure and happy coding! ```