HolyGhost logoHolyGhost
← cd ..
Analysis

Clickjacking: When the Button You Click Is Not the Button You See

Clickjacking layers an invisible page over a decoy so your click lands somewhere you never intended. Here is how this user interface trick works and how sites shut it down.

HolyGhost··8 min read

You land on a cheerful page that says "Click here to claim your prize". You click the big green button. Nothing much seems to happen, maybe the page shrugs and moves on. What you did not see is that your click never touched that button at all. It passed straight through an invisible sheet of glass and landed on a completely different website underneath, one where you happened to be logged in, and it quietly changed a setting, followed an account, or approved something on your behalf.

That is clickjacking, and the unsettling part is that everything you saw on screen was a lie of positioning. This is a walk through of how the trick works, why it is so effective, and the small settings that stop it dead.

Credit and scope

The term clickjacking was coined by the researchers Jeremiah Grossman and Robert Hansen in 2008. This is a defensive explainer of how the technique works, for people building and protecting websites. Only ever test against sites you own or are authorised to assess.

The core idea: two pages, one click

To follow clickjacking you need one piece of web vocabulary. An iframe (short for inline frame) is a way for one web page to embed another web page inside it, like a window showing a different site within the current one. Iframes are everywhere and mostly harmless: embedded videos, maps, and payment widgets are often iframes.

Clickjacking abuses this. The attacker builds a decoy page they control, and inside it they load the real target site in an iframe. Then they use styling to make that iframe completely transparent and stretch it over the decoy, lining up an important button on the target with the tempting button on the decoy.

What the victim sees:        [  CLAIM YOUR PRIZE  ]   (the decoy)
 
What is really there:        [  transparent target site on top  ]
                             the hidden "Delete account" button
                             sits exactly over "CLAIM YOUR PRIZE"
 
The click passes through to the hidden button underneath.

The victim aims for the visible decoy button, but the transparent target layer is on top, so the browser delivers the click to the hidden button instead. Because the victim is already logged in to the target in another tab or from a saved session, the action runs with their full authority. They authorised it, in the browser's eyes, because they physically clicked.

Why it feels impossible at first

It seems like the browser should not let one site receive clicks meant for another. But from the browser's point of view nothing is wrong: a page is allowed to embed another page, and a click is a click. The attack lives entirely in the visual layering, which the user cannot see. There is no broken rule, only a broken assumption that what you see is what you click.

What an attacker can achieve

Clickjacking only lets the attacker make you click (and with more effort, drag or type), so it is limited to actions that a click can trigger on the target. But that is a surprisingly rich list when you are already logged in:

  • Likejacking, the original party trick, where you unknowingly like or follow something, inflating a page or spreading a scam.
  • Flipping an account setting, for example switching a privacy control off or enabling a feature that helps the attacker.
  • Approving a connected application or a permission prompt.
  • In the worst cases, confirming a payment, a transfer, or a deletion, where a single well placed click does real damage.

The attacker cannot read the target page or steal data directly through the click. What they get is the ability to perform an action as you, on a site that trusts you.

A close cousin of CSRF

Clickjacking sits right next to cross site request forgery. Both abuse the fact that you are logged in to a target and trick your browser into acting with your authority. The difference is the mechanism. Cross site request forgery forges a request behind the scenes. Clickjacking makes you perform the action yourself, by hijacking a real click. Because a genuine click is involved, some defences that stop forged requests do not stop clickjacking, which is why it needs its own fix.

Why the decoy is so convincing

The craft of a clickjacking attack is in the alignment and the lure. The attacker studies the target, finds the exact pixel position of the button they want, and builds a decoy whose tempting element sits precisely there. They pick lures that naturally invite rapid, repeated clicking: a game, a "prove you are human" checkbox, a video that needs a click to play, a cookie banner to dismiss. Anything that trains you to click without thinking.

Some versions go further and follow your cursor, so the invisible button is always under the pointer wherever you move, guaranteeing the hit. Others chain several clicks together to walk you through a multi step action, one disguised click at a time. None of this shows on screen. To the victim it is just a slightly janky web page.

How sites shut it down

Here is the good news. Clickjacking has clean, reliable defences, and they live on the target site rather than depending on the user to be careful. The core idea is simple: a sensitive site should refuse to be embedded in someone else's page in the first place. If the target cannot be put inside a hostile iframe, there is nothing to lay a decoy over.

There are two headers a site can send to enforce that. A header is a small instruction the server attaches to its response to tell the browser how to behave.

  1. X-Frame-Options. The older of the two. Setting it to DENY tells browsers the page may never be shown inside a frame at all. Setting it to SAMEORIGIN allows the page to frame itself but blocks other sites from framing it. Simple and widely supported.
X-Frame-Options: DENY
  1. Content-Security-Policy: frame-ancestors. The modern replacement, part of the broader Content Security Policy system. The frame-ancestors directive lists exactly who, if anyone, is allowed to embed the page. frame-ancestors 'none' is the strongest, refusing all framing.
Content-Security-Policy: frame-ancestors 'none'

Use frame-ancestors, and X-Frame-Options for older browsers

The current best practice is to set the Content Security Policy frame-ancestors directive, because it is more flexible and is the standard going forward. Many teams also send X-Frame-Options alongside it to cover older browsers that predate the policy. Set them on every sensitive page, not just the login screen.

A third measure helps too. Marking session cookies as SameSite (which controls whether cookies ride along on cross site requests) reduces what a framed session can do, and it is good practice for many reasons, including cross site request forgery.

What not to rely on

For years, sites tried to defend themselves with framebusting scripts: JavaScript in the page that detects when it has been loaded inside a frame and tries to break out or blank itself. It sounds sensible, but attackers found reliable ways around these scripts, and they fail entirely if the victim's browser has JavaScript restricted. Framebusting is a historical footnote, not a defence. Use the headers instead, because they are enforced by the browser itself rather than by fragile page code.

Seeing it in the bigger picture

Clickjacking is a lesson in a theme that runs through a lot of web security: the gap between what the user perceives and what the system actually does. The same theme underlies cross site scripting, where a page runs code the user never intended, and phishing, where a site is not who it appears to be. Once you start noticing that gap, a great deal of web attack technique becomes easier to reason about. If you want the underlying model of how a page is requested and rendered in the first place, our primer on how the web works sets the scene.

The takeaway

Clickjacking works by stacking an invisible copy of a target site over an attractive decoy, so the click you aim at the decoy actually lands on a hidden button on the target, performed with your own logged in authority. It is visual trickery, not a broken browser rule, which is why the fix is to stop sensitive pages being framed at all. Send the Content Security Policy frame-ancestors directive, keep X-Frame-Options for older browsers, mark session cookies SameSite, and forget about fragile framebusting scripts. Do that, and there is no glass sheet for an attacker to lay over your buttons.