Clickjacking: clicks on a page the user cannot see

Clickjacking is an attack in which another site loads your page in an invisible frame and places it over a decoy, so a user who thinks they are clicking a button on the decoy clicks a button on your page instead. Because the user is signed in to your site, the click counts: a setting changes, a payment is confirmed, permissions are granted. The fix is to tell browsers who may frame your pages.

Section Web attacks Updated Weakness CWE-1021

Quick facts

Also called
UI redressing
Weakness
CWE-1021: improper restriction of rendered UI layers or frames
OWASP category
A06:2025 Insecure Design, by CWE mapping; see OWASP Top 10
Main fix
The frame-ancestors directive of Content Security Policy, with X-Frame-Options for older browsers
Does a WAF stop it?
No. The attack happens in the browser; the requests to your site are the user's own

Definitions follow OWASP and CWE-1021.

How a clickjacking attack works

  1. The attacker builds a decoy page. A game, a prize, a video with a play button.
  2. Your page is loaded in a frame on top of it, made transparent and positioned so your button sits exactly under the decoy's.
  3. The user clicks the decoy. The click goes to your page, in the user's signed-in session.
  4. Your site carries out the action. From its point of view the user clicked a real button on a real page.

Variants move the frame with the pointer, ask for several clicks in sequence, or drag text into a form. All of them depend on one thing: your page agreeing to be framed by another site.

Clickjacking examples

  • Changing settings. A privacy or email setting switched by a single hidden click.
  • Confirming an action. A purchase, transfer or deletion that needs only one confirmation click.
  • Granting permissions. Camera, microphone or account access approved on a page the user cannot see.
  • Social actions. A follow, like or share that spreads the decoy further.

The common pattern is an action that needs no typing and no second step, which is also the first thing to protect.

FRAME PROTECTION OPTIONS BLOCKS OTHER SITES ALLOWS NAMED PARTNERS OLDER BROWSERS COVERED NO HEADER X-FRAME-OPTIONS SAMEORIGIN FRAME-ANCESTORS 'SELF' FRAME-ANCESTORS + XFO // frame-ancestors can list partners; X-Frame-Options cannot
// four setups, and why both headers are sent together

Why frame-busting scripts are not enough

Before browsers supported headers for this, sites added scripts that checked whether the page was framed and, if so, replaced the outer page. These frame-busting scripts can be defeated: the framing page can sandbox the frame so scripts do not run, or interfere with navigation so the replacement never happens.

Headers do not have that weakness, because the browser enforces them before the page renders. Keep a script only as a fallback for very old browsers, never as the main defence.

How to prevent clickjacking

  1. Send frame-ancestors. Content-Security-Policy: frame-ancestors 'self' stops other sites framing your pages; list partner origins if they need to embed you. See frame-ancestors on MDN.
  2. Send X-Frame-Options as well. X-Frame-Options: SAMEORIGIN for browsers that do not support the directive; see X-Frame-Options on MDN.
  3. Set SameSite on session cookies. A framed page loaded from another site then often arrives without the session.
  4. Confirm sensitive actions. Re-entering a password defeats a hidden click.

The OWASP Clickjacking Defense Cheat Sheet explains why script-based frame busting is not enough. Both headers are part of the set on HTTP security headers.

How to test for clickjacking

Check the response headers of a page with a sensitive action: if neither frame-ancestors nor X-Frame-Options is present, the page can be framed. You can confirm by creating a local HTML file with an iframe pointing to the page and opening it in a browser; if the page appears, it is frameable.

Test signed-in pages and error pages, not only the home page; headers set in one part of a site are often missing from another.

Questions

What is clickjacking?

Clickjacking is an attack in which another site loads your page in an invisible frame over a decoy, so a user's click on the decoy lands on a button on your page.

How do you prevent clickjacking?

Send Content-Security-Policy with frame-ancestors 'self', plus X-Frame-Options: SAMEORIGIN for older browsers, set SameSite on session cookies, and confirm sensitive actions.

Can a WAF stop clickjacking?

No. The attack happens in the user's browser and the requests to your site are the user's own; frame protection headers set by your site stop it.

How do I test my site for clickjacking?

Check whether pages send frame-ancestors or X-Frame-Options, and try loading a sensitive page in an iframe from a local file; if it appears, it can be framed.