How does clickjacking work?
An attacker embeds a legitimate page in a transparent or disguised iframe and aligns sensitive controls beneath decoy content. A visitor believes they are clicking the attacker’s interface while actually activating a button on the framed site.
The risk is greatest for pages with state-changing actions: approving access, changing account settings, making purchases, or authorizing transfers. Visual design alone cannot stop hostile framing.
Should I use X-Frame-Options or frame-ancestors?
CSP frame-ancestors is the modern, flexible control. Set it to none when no framing is allowed, self for same-origin framing, or list the exact trusted origins that may embed the page.
X-Frame-Options remains useful as a compatibility layer with DENY or SAMEORIGIN. Its obsolete ALLOW-FROM directive is ignored by modern browsers, so use frame-ancestors when specific third-party origins must be supported.
How do I fix a failed clickjacking test?
For sites that never need framing, send Content-Security-Policy: frame-ancestors none and X-Frame-Options: DENY. If your own application uses frames, choose self or an explicit origin list after testing each workflow.
Set the headers on every HTML response, especially authentication and account pages. JavaScript frame-busting snippets are weaker because they can be bypassed, disabled, or affected by sandbox behavior.
Frequently asked questions
Does X-Frame-Options work in a meta tag?
No. It must be an HTTP response header. Browsers do not enforce X-Frame-Options from a meta element.
Is SAMEORIGIN enough?
It is suitable when only same-origin framing is needed. frame-ancestors offers clearer and more flexible control.
Can JavaScript prevent clickjacking?
Frame-busting scripts are not a reliable replacement for browser-enforced response headers.