How can you prevent clickjacking attacks?
TL;DR
Prevent clickjacking at the server boundary with the Content Security Policy frame-ancestors directive. Use 'none' when the page must never be framed, 'self' for same-origin embedding, or an explicit list of trusted origins. X-Frame-Options: DENY or SAMEORIGIN remains a useful fallback for older clients, but cannot express a modern multi-origin allowlist. JavaScript “frame-busting” code is not a reliable primary defense.
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
What is clickjacking?
Clickjacking is a type of attack where a malicious site tricks users into clicking on something different from what the user perceives, potentially leading to unauthorized actions or information disclosure. This is often achieved by embedding the target site in an invisible iframe and overlaying it with deceptive content.
How to prevent clickjacking attacks
Using the X-Frame-Options header
The X-Frame-Options HTTP header can be used to control whether a browser should be allowed to render a page in a <frame>, <iframe>, <embed>, or <object>. This header has two valid values:
DENY: Prevents the page from being displayed in a frame, regardless of the site attempting to do so.SAMEORIGIN: Allows the page to be displayed in a frame on the same origin as the page itself.
A third value, ALLOW-FROM uri, is obsolete and not supported by modern browsers. To allow specific origins to frame your page, use the CSP frame-ancestors directive instead.
Example:
X-Frame-Options: DENY
Using the Content-Security-Policy header
The Content-Security-Policy (CSP) header provides a more flexible and modern approach to prevent clickjacking. The frame-ancestors directive specifies valid parents that may embed a page using <frame>, <iframe>, <object>, <embed>, or <applet> tags.
Example:
Content-Security-Policy: frame-ancestors 'self'
This directive can also specify multiple origins or use wildcards for more complex scenarios.
Example:
Content-Security-Policy: frame-ancestors 'self' https://trusted.com
Combining both headers
For compatibility with older clients, sites often send both headers with equivalent policies. Modern browsers that enforce frame-ancestors use it in preference to X-Frame-Options.
Example:
X-Frame-Options: SAMEORIGINContent-Security-Policy: frame-ancestors 'self'
These protections must be delivered as HTTP response headers; frame-ancestors is not supported in a <meta> policy. Test every page that performs sensitive actions, including error and authentication pages. SameSite cookies and re-authentication for high-risk actions can reduce impact, but do not replace a framing policy.
Further reading
- MDN Web Docs: X-Frame-Options
- MDN Web Docs: Content-Security-Policy
- OWASP: Clickjacking Defense Cheat Sheet