Clickjacking: What It Is and How to Prevent It
Clickjacking, also called UI redressing, tricks users into clicking something different from what they think they are clicking. The attacker loads your page in an invisible frame on top of their own page, and positions a decoy button over a real button in your app.
How the attack works
- The attacker builds a page offering something enticing, such as "Click to claim your prize."
- They embed your app's settings page in a transparent
iframelayered on top. - The victim, already logged into your app, clicks the decoy.
- The click actually lands on your real button: "Delete account," "Make repository public," or "Approve OAuth access."
<iframe src="https://app.example.com/settings/danger" style="opacity:0;position:absolute;top:0;left:0;width:100%;height:100%"></iframe>
<button>Claim prize</button>
When clickjacking is a real risk
The risk depends on what a single click, or a few clicks, can do:
- High risk: one-click destructive or permission-granting actions, such as OAuth consent screens, payment confirmations, enabling sharing or deleting data.
- Lower risk: pages with no state-changing actions, or actions that require typing data.
Bug bounty programmes often rate clickjacking on pages without sensitive actions as informational.
How to prevent clickjacking
Content Security Policy frame-ancestors
The modern and most flexible control:
Content-Security-Policy: frame-ancestors 'none'
Or allow only your own origin and specific partners:
Content-Security-Policy: frame-ancestors 'self' https://partner.example
X-Frame-Options
The older header, still widely supported:
X-Frame-Options: DENY
or SAMEORIGIN. Set both headers for compatibility. If both are present, modern browsers prefer frame-ancestors.
Defence in depth for sensitive actions
- Require confirmation steps that involve typing, such as entering the project name to delete it.
- Require re-authentication for critical actions.
- Use
SameSitecookies, which limit authenticated content inside cross-site frames.
Why JavaScript frame busting is not enough
Older sites used scripts that break out of frames. Attackers can defeat these with sandboxed iframes and other tricks. Use headers instead.
Embeddable widgets
If your product must be embedded, such as a chat widget or booking form, allow framing only for the embed routes, and keep account settings and admin pages unframeable.
Testing for clickjacking
SecurityInfinity checks every discovered page for framing protections and highlights pages where sensitive actions can be framed. Start free.
Frequently asked questions
Is a missing X-Frame-Options header always a vulnerability?
It is a missing protection. Whether it is exploitable depends on whether the page has sensitive one-click actions.
Does frame-ancestors work in meta tags?
No. frame-ancestors must be sent as an HTTP response header, not in a meta tag.
Can clickjacking steal data?
Typically it triggers actions rather than reading data, but it can be combined with other techniques to leak limited information.