Clickjacking, also called a UI redress attack, is a web attack in which a malicious page loads a legitimate site inside an invisible or disguised frame and tricks the user into clicking elements of that hidden site. In application security it is classified as a client-side interface manipulation: the victim believes they are pressing a harmless button, while the click actually lands on a control in the framed application, where they are already logged in.
Because the click is a genuine user action inside an authenticated session, the target application sees a perfectly valid request. Clickjacking has been used to change account settings, grant camera or microphone permissions, follow or like content on social networks and approve transactions. The standard defense is to forbid untrusted framing with the Content Security Policy directive frame-ancestors or the older X-Frame-Options header.
How a clickjacking attack works
The attacker builds a decoy page with an attractive element, such as a game, a prize button or a video play icon. On top of it, or beneath it, the page loads the target application in an iframe and makes it transparent with CSS, typically opacity: 0, while positioning the frame so that a sensitive button lies exactly under the decoy element.
When the victim clicks, the browser delivers the event to the topmost element at that point, which is the invisible frame. The target site receives the click with the victim’s cookies and session, so the action succeeds. Attacks often need several clicks, so the decoy page moves the frame between clicks or guides the victim through a multi-step game.
| Building block | Purpose | Typical technique |
|---|---|---|
| Target frame | Loads the authenticated victim site | iframe pointing to a settings or action page |
| Transparency | Hides the real interface | CSS opacity near zero |
| Alignment | Places the sensitive control under the decoy | Absolute positioning and offsets |
| Decoy content | Motivates the click | Game, prize, fake captcha or play button |
| Click sequencing | Completes multi-step actions | Repositioning the frame between clicks |
Variants of UI redress attacks
The basic idea has been adapted to many interaction types. All of them exploit the gap between what the user sees and what the browser actually receives.
| Variant | What is hijacked | Example goal |
|---|---|---|
| Classic clickjacking | Single mouse click | Change a security setting |
| Likejacking | Social media buttons | Make the victim like or share content |
| Cursorjacking | Displayed cursor position | Click where the user did not aim |
| Drag-and-drop jacking | Drag events across frames | Extract text or tokens from the target |
| Keystroke redirection | Typed input | Enter data into a hidden form field |
| Double-clickjacking | Timing between two clicks | Swap windows so the second click approves an action |
Double-click variants are a reminder that frame-busting is not the whole story. They open or switch windows between the first and second click of a double-click, so the second click lands on a real, unframed page. Defending against them requires interaction delays or confirmation design for sensitive actions in addition to framing controls.
Clickjacking compared with CSRF and XSS
Clickjacking is often confused with neighboring Terms in application security. The difference lies in who issues the request and what the attacker controls.
| Aspect | Clickjacking | CSRF | XSS |
|---|---|---|---|
| Attacker controls | Layout of a third-party page | A forged request from another site | Script running inside the target site |
| User action needed | Yes, real clicks | Usually only visiting a page | Usually only visiting a page |
| Bypasses CSRF tokens | Yes, the real form submits them | No | Yes |
| Main defense | frame-ancestors, X-Frame-Options | Tokens, SameSite cookies | Output encoding, CSP |
The important consequence is that anti-CSRF tokens do not stop clickjacking: the victim clicks the genuine form, so the token is included automatically. SameSite cookies help only partly, because the default Lax setting already withholds cookies from cross-site iframes, but sites that set SameSite=None for embedding remain exposed.
Defending against clickjacking
The primary defense is a server-side framing policy that tells the browser which origins may embed a page. Modern browsers enforce it before rendering, so the attack page receives an empty or blocked frame.
| Control | Example value | Notes |
|---|---|---|
| CSP frame-ancestors | frame-ancestors ‘none’ | Preferred; supports lists of allowed origins |
| CSP frame-ancestors with allowlist | frame-ancestors ‘self’ partner origin | For pages that legitimately embed |
| X-Frame-Options | DENY or SAMEORIGIN | Legacy fallback; ALLOW-FROM is obsolete |
| JavaScript frame-busting | Checks top against self | Unreliable; bypassable with sandboxed frames |
| SameSite cookies | Lax or Strict | Removes the session in cross-site frames |
| Re-authentication or confirmation | Password or step-up prompt | Protects the most sensitive actions |
Best practice is to send frame-ancestors ‘none’ on every page that has no reason to be embedded, add X-Frame-Options: DENY for older clients, and define narrow allowlists only for widgets that are meant to be framed. These headers belong in the standard set of security headers applied by the web server or framework.
Testing and common mistakes
Testing is simple: create a local HTML page that frames the target URL and check whether it renders. Automated scanners flag missing framing headers, and the OWASP testing guidance lists clickjacking as a standard check. Several recurring mistakes leave applications exposed:
- Protecting only the login page while account settings, payment and permission pages remain frameable.
- Relying on JavaScript frame-busters, which attackers disable with the iframe sandbox attribute.
- Inconsistent headers across microservices, CDNs or error pages served by different components.
- Overly broad allowlists such as a wildcard that permits any subdomain, including user-controlled ones.
The simple explanation
Imagine signing what looks like a petition, while someone has slipped a sheet of clear plastic over it with a different document underneath. Your signature lands on the hidden paper, not the one you can see. Clickjacking does this with web pages: a harmless-looking button sits on top of an invisible copy of a real site where you are logged in.
When you click, the real site believes you pressed its button. Websites stop this by refusing to be shown inside other sites’ pages, which takes away the invisible layer.
How it is used in practice
During a security review of an online banking portal, a tester notices that the page for adding a new payee sends no framing headers. The tester builds a page with a fake quiz whose answer buttons line up with the portal’s form fields and its confirm button, prefilled through URL parameters. A logged-in test customer who plays the quiz unknowingly adds the tester’s account as a trusted payee.
The bank’s developers add Content-Security-Policy: frame-ancestors 'none' and X-Frame-Options: DENY at the reverse proxy for every route, and require a one-time code for new payees. A repeat test shows an empty frame on the quiz page, and the payee page can no longer be triggered from outside the bank’s own site.