security
How to fix: X-Frame-Options / frame-ancestors
OWASP A05
RFC 7034
Why this matters
Clickjacking attacks load your site in a hidden iframe on a malicious page and trick the visitor into clicking your buttons without realising. X-Frame-Options stops your pages from being framed.
Background
X-Frame-Options (legacy) and CSP frame-ancestors (modern) prevent attackers from embedding your site inside an iframe on an attacker-controlled page — a UI-redress (clickjacking) attack. Set both for compatibility; frame-ancestors in CSP supersedes X-Frame-Options where the browser supports it.
References
RFC 7034 · OWASP A05 · Clickjacking defence
How to fix
Code snippet for each stack we cover. Pick the one matching your server / framework.
nginx
add_header X-Frame-Options "DENY" always; # AND in CSP: frame-ancestors 'self';
apache
Header always set X-Frame-Options "DENY"
cloudflare
Transform Rules → response header → X-Frame-Options: DENY (or SAMEORIGIN if you legitimately embed your own site).
wordpress
Headers Security Advanced plugin sets both.
flask
Flask-Talisman includes 'X-Frame-Options: SAMEORIGIN' by default.
express
helmet.frameguard({ action: 'deny' })
rails
Included by default in Rails secure headers.
Verify it's working
curl -sI https://your-site/ | grep -i 'x-frame-options\|frame-ancestors'
Want to know if your site has this issue?
Run a free 53-check audit — security, GDPR, NIS2, and technical SEO.
Audit my site →