Why X-Frame-Options: ALLOW-FROM doesn't protect you anymore

Clickjacking works by loading your page inside an invisible or disguised <iframe> on an attacker's site, then tricking a visitor into clicking something that is really a button on your page underneath -- a "log in with Google" prompt, a "confirm transfer" button, a cookie-consent toggle. The defence is telling the browser which sites, if any, are allowed to frame your page at all, and two different headers can say so.

frame-ancestors does not fall back to default-src

Most Content-Security-Policy directives that control where a resource can load from -- script-src, img-src, connect-src, and others -- fall back to default-src when they aren't explicitly set. frame-ancestors is a navigation directive, not a fetch directive, and the CSP specification does not give it that fallback. A policy of default-src 'self' alone gives the page no clickjacking protection from CSP -- the directive has to be spelled out on its own.

Three states, and only one header combination tells you which

What's presentActually protected in current browsers?
CSP frame-ancestors set (to anything but *)Yes -- takes precedence over X-Frame-Options everywhere
No frame-ancestors, but X-Frame-Options: DENY or SAMEORIGINYes
No frame-ancestors, only X-Frame-Options: ALLOW-FROM https://example.comNo -- every current major browser engine ignores the ALLOW-FROM value entirely
Neither header presentNo

The third row is the one worth checking for by name: it is the only case where a header is present, looks correct, and still leaves the page completely unprotected -- a raw curl -I dump reads it as "has X-Frame-Options" with no way to tell that a browser will not honour it.

Check your own site automatically

The checker on this site sends one real request, applies these CSP fallback and ALLOW-FROM rules, and reports which of the three states above your response is in -- plus whether your CSP's effective script-src allows 'unsafe-inline' with no nonce or hash to override it, or a wildcard host source, and whether the response has Strict-Transport-Security at all. The request comes from a Node CLI you run yourself against a system you own or are authorised to test; the browser page only renders a report you paste in.

This is evidence from that one response, not a full security assessment -- see the checker and its disclaimer for what it does and doesn't cover.

← Back to the checker