What Is Clickjacking and How Do You Prevent It?
Learn how clickjacking works via hidden iframes and how X-Frame-Options and CSP frame-ancestors prevent it, with examples.
Expected Interview Answer
Clickjacking is an attack where a malicious page overlays or embeds a legitimate site inside a transparent or disguised iframe, tricking a user into clicking on the hidden real page’s buttons while believing they are interacting with the visible decoy content.
The attacker crafts a page with an enticing UI — a game, a “claim your prize” button — and stacks an invisible iframe of the target site (say, a banking transfer confirmation or a social media “like” button) precisely on top of it using CSS opacity and positioning. When the user clicks what they believe is the decoy button, the click actually lands on the hidden real page underneath, triggering an action the user never consciously agreed to, since the browser reports the click as a genuine same-origin interaction on the framed site. The primary defense is telling browsers not to allow the page to be framed at all, via the X-Frame-Options header (DENY or SAMEORIGIN) or the more flexible Content-Security-Policy frame-ancestors directive, which also supports allow-listing specific origins. A secondary, JavaScript-based defense (frame-busting scripts) exists for legacy browsers but is less reliable and can itself be bypassed, so header-based framing controls are the standard, authoritative fix.
- X-Frame-Options / frame-ancestors stops the browser from rendering the page inside a hostile iframe at all
- Removes the attack surface at the browser level rather than relying on fragile client-side detection
- frame-ancestors additionally supports allow-listing legitimate embedding origins (e.g., trusted partner sites)
- Combines well with SameSite cookies to reduce the broader class of cross-site interaction attacks
AI Mentor Explanation
Clickjacking is like a prankster placing an invisible, perfectly aligned actual scoring-desk button underneath a fake “ring the bell” button on a stall. A fan believes they are just ringing a bell for fun, but their finger actually presses the real scoring desk’s confirm button hidden beneath it. The fix is the scoring desk refusing to ever let its interface be physically stacked under someone else’s stall in the first place. That refuse-to-be-overlaid defense is exactly what framing-control headers provide against clickjacking.
Step-by-Step Explanation
Step 1
Attacker builds a decoy page
A page with an enticing visible UI is crafted to lure the victim into clicking.
Step 2
Attacker overlays a transparent iframe
The real target page is embedded via iframe, made invisible or nearly so, and precisely positioned over the decoy button.
Step 3
Victim clicks the decoy
The click lands on the hidden real page underneath, which the browser treats as a genuine same-origin interaction.
Step 4
Unintended action executes
The hidden site performs the real action (transfer, like, delete) the victim never consciously chose.
What Interviewer Expects
- Correct description of the transparent-iframe-overlay mechanism
- Naming X-Frame-Options and/or CSP frame-ancestors as the primary defense
- Understanding that this is a browser-enforced, server-header-driven fix, not purely client-side JavaScript
- Awareness that frame-busting JS scripts are a weaker legacy fallback, not the primary defense
Common Mistakes
- Confusing clickjacking with CSRF (clickjacking tricks a real user into a real click; CSRF forges a request without user awareness of clicking anything at all)
- Relying only on a JavaScript frame-busting script instead of the authoritative header-based control
- Forgetting that CSP frame-ancestors can allow-list legitimate partner origins, unlike a blanket DENY
- Not mentioning that this is enforced by the browser refusing to render the frame, not by detecting the click itself
Best Answer (HR Friendly)
“Clickjacking is when an attacker hides a real button from a legitimate site under something that looks harmless, like a game or a prize button, so when you click what you think is the harmless thing, you are actually clicking the real hidden button underneath and triggering an action you never meant to take. Sites prevent it by telling browsers, through a security header, that they are simply not allowed to be shown inside someone else’s frame at all.”
Code Example
app.use((req, res, next) => {
// Legacy header: block all framing entirely
res.setHeader('X-Frame-Options', 'DENY')
// Modern, more flexible: allow only same-origin framing
res.setHeader(
'Content-Security-Policy',
"frame-ancestors 'self'"
)
next()
})Follow-up Questions
- How does CSP frame-ancestors differ from X-Frame-Options, and why might you need both?
- How does clickjacking differ from CSRF in terms of what the browser and user actually do?
- Why are JavaScript frame-busting scripts considered an unreliable defense?
- How could clickjacking be combined with a fake cursor to defeat visual cues entirely?
MCQ Practice
1. What is the core mechanism behind a clickjacking attack?
Clickjacking relies on visually hiding the real target page behind or under a decoy so real clicks trigger unintended actions.
2. What is the primary, authoritative defense against clickjacking?
Browser-enforced framing-control headers are the standard, reliable defense; JS frame-busting is a weaker fallback.
3. How does clickjacking differ from CSRF?
Clickjacking hijacks a genuine user click via visual deception; CSRF forges a request using the victim’s ambient credentials, no click required.
Flash Cards
What is clickjacking? — Tricking a user into clicking a hidden, transparently framed real page while showing a decoy UI on top.
Primary defense header? — X-Frame-Options (DENY/SAMEORIGIN) or CSP frame-ancestors.
Clickjacking vs CSRF? — Clickjacking hijacks a real click via visual deception; CSRF forges a request without a specific click.
Why avoid frame-busting JS alone? — It is a legacy, bypassable client-side defense; header-based controls are authoritative.