Back to all terms
Securitybasic

Clickjacking Prevention (X-Frame-Options)

Techniques to prevent attackers from tricking users into clicking hidden or disguised elements by embedding your site in an iframe.

Also known as: X-Frame-Options, frame busting, UI redressing prevention, iframe security

Description

Clickjacking, also known as UI redressing, is an attack where a malicious website embeds your application in a transparent or disguised iframe and tricks users into clicking elements they didn't intend to interact with. The attacker overlays their own UI on top of or beneath the hidden iframe, so when users think they're clicking a button on the visible page, they're actually clicking a button on your hidden application -- potentially changing account settings, making purchases, or granting permissions.

The primary defense against clickjacking is preventing your pages from being framed by untrusted sites. The X-Frame-Options HTTP header was the original solution, offering three values: DENY (never allow framing), SAMEORIGIN (only allow framing by the same origin), and ALLOW-FROM (allow framing by a specific origin, though this is deprecated and poorly supported). The modern replacement is the Content Security Policy frame-ancestors directive, which provides more flexible control over framing permissions.

For applications that need to support legitimate embedding (widgets, payment forms, SSO flows), frame-ancestors can specify exact allowed origins. JavaScript-based frame busting (checking if window.top !== window.self) is unreliable as a sole defense since it can be bypassed with sandbox attributes on iframes. The recommended approach is to use both the X-Frame-Options header (for legacy browser support) and the CSP frame-ancestors directive (for modern browsers), with DENY or 'none' as the default for pages that should never be framed.

Prompt Snippet

Set both X-Frame-Options: DENY and Content-Security-Policy: frame-ancestors 'none' headers on all responses by default. For pages that legitimately need embedding (payment widgets, SSO callbacks), use frame-ancestors with specific allowed origins: frame-ancestors 'self' https://trusted-partner.com. Configure these headers at the reverse proxy level (nginx add_header, Caddy header directive) to ensure consistent application across all routes. Avoid relying on JavaScript frame-busting scripts (if (top !== self) top.location = self.location) as they can be bypassed with the sandbox iframe attribute. Test framing protection using browser DevTools or OWASP ZAP's clickjacking scanner.

Tags

clickjackingx-frame-optionsiframe-securityui-redressing