X-Frame-Options DENY vs SAMEORIGIN vs CSP frame-ancestors (tested in Chrome)
Both headers stop clickjacking by controlling who may show your page in an iframe. We framed a test page with each one, from the same origin and from another origin.
1. Results
| Header on the framed page | Framed by same origin | Framed by another origin |
|---|---|---|
| (none) | Shown | Shown |
X-Frame-Options: DENY | Blocked | Blocked |
X-Frame-Options: SAMEORIGIN | Shown | Blocked |
X-Frame-Options: ALLOW-FROM https://other | Shown | Shown, from any site |
Content-Security-Policy: frame-ancestors 'none' | Blocked | Blocked |
frame-ancestors 'self' | Shown | Blocked |
frame-ancestors 'self' https://other | Shown | Shown (listed origin) |
X-Frame-Options: DENY + frame-ancestors https://other | Blocked | Shown (listed origin) |
2. What this means
- DENY = nobody may frame the page, not even your own site. SAMEORIGIN = only pages from the same origin (scheme, host and port).
- ALLOW-FROM doesn't work in Chrome. It was ignored completely, so the page could be framed by any site: worse than sending nothing, because it looks protected. To allow specific sites, use
frame-ancestors. - frame-ancestors wins. When a page sent both headers, Chrome followed the CSP and ignored
X-Frame-Options: DENY. Keep both consistent. Older browsers that don't support CSP still read X-Frame-Options.
3. What to send
Content-Security-Policy: frame-ancestors 'self'
X-Frame-Options: SAMEORIGIN
Or 'none' with DENY if your pages are never framed, not even by yourself. If you already send a Content-Security-Policy, add frame-ancestors to it rather than sending a second CSP header. frame-ancestors only works as an HTTP header: the CSP specification says browsers ignore it in a <meta> tag (not tested here). Build a full policy with the free security headers generator.
Frequently asked questions
What is the difference between DENY and SAMEORIGIN?
DENY blocks all framing, including by your own site. SAMEORIGIN allows frames only from the same scheme, host and port. In our Chrome test, SAMEORIGIN blocked a page on another port of the same host.
Is X-Frame-Options deprecated?
It is superseded by CSP frame-ancestors, which overrode it in our Chrome test. It is still worth sending for older browsers, with the same rule.
How do I allow one other site to frame my page?
Use Content-Security-Policy: frame-ancestors 'self' https://partner.example. ALLOW-FROM was ignored by Chrome in our test.
Why does my page refuse to load in an iframe?
The framed page (not yours) sends X-Frame-Options or frame-ancestors. Only that site can change it. Check its response headers in DevTools → Network.
Written with AI assistance. Each header was tested on 2026-10-01 by framing a test page in Chromium 153 from the same origin and from a different origin (another port). PlainHeaders is our extension; the other methods are free.