← Back to All Vulnerabilities

Clickjacking Vulnerability

Clickjacking (also known as UI redress attack) is a technique where attackers trick users into clicking something different from what they perceive, by overlaying transparent elements over legitimate buttons or links.

Interactive Clickjacking Demonstration

This demo shows how a clickjacking attack works. The transparent layer makes you think you're clicking "Claim Your Prize", but you're actually clicking "Delete Account".

The decoy layer (what the user sees) is shown on top of the victim layer (what the user actually interacts with).

Win a Free Prize!

Congratulations! You've been selected to receive a free gift card. Click the button below to claim your prize!

Account Settings

Warning: This action cannot be undone!

In this more realistic example, we have two separate web pages:

  1. The victim website with a delete account button
  2. The attacker website that frames the victim and overlays a deceptive interface

Victim Website (what you're really clicking on):

Attacker Website (what you think you're clicking on):

Real-World Implications

Clickjacking attacks can be used to trick users into:

Types of Clickjacking

How to Prevent Clickjacking

1. X-Frame-Options Header

The X-Frame-Options HTTP header can prevent your site from being loaded in an iframe:

// Server-side code (e.g., in Node.js)
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
        

Options include:

2. Content Security Policy (CSP)

The CSP header with frame-ancestors directive provides more flexibility:

// Server-side code
res.setHeader('Content-Security-Policy', "frame-ancestors 'self'");
        

Options include:

3. Frame-busting JavaScript

Client-side JavaScript can detect and break out of iframes:

// Add this to your page
if (top !== window) {
    top.location = window.location;
}
        

Or a more comprehensive version:

(function() {
    // First, apply an initial CSS style to hide the content
    var style = document.createElement('style');
    style.innerHTML = 'html { display: none !important; }';
    document.head.appendChild(style);
    
    // Then check if we're being framed
    if (self === top) {
        // We're not in a frame, show the content
        var style = document.getElementsByTagName('style')[0];
        document.head.removeChild(style);
    } else {
        // We're in a frame, break out
        top.location = self.location;
    }
})();