X-Frame-Options.
Prevents your site from being embedded in malicious iframes (clickjacking)
What does this check test?
The `X-Frame-Options` header controls whether a browser should be allowed to render your page inside an `<iframe>`, `<frame>`, or `<object>`. It accepts three values: `DENY` (never allow framing), `SAMEORIGIN` (allow framing only by pages on the same origin), or `ALLOW-FROM uri` (allow framing from a specific URI, though browser support is limited). This header has been largely superseded by CSP's `frame-ancestors` directive, but remains important for backward compatibility.
Why does it matter?
Clickjacking attacks trick users into clicking on hidden elements by overlaying your site inside a transparent iframe on a malicious page. An attacker might overlay a 'Transfer Funds' button with a seemingly innocent 'Play Video' button. Without framing protection, any authenticated action on your site can be hijacked this way. X-Frame-Options is simple to deploy and provides immediate clickjacking protection across all major browsers.
Who is affected?
Any site with authenticated functionality, form submissions, or state-changing actions needs clickjacking protection. Banking, e-commerce, and SaaS applications are especially at risk. Even sites that seem low-value can be used as clickjacking vectors to harvest credentials or trick users into granting permissions. The only sites that may intentionally allow framing are embeddable widgets or content designed for iframe distribution.
Where does this apply?
Set the `X-Frame-Options` header on all HTML page responses from your server, CDN, or load balancer. It applies only to the top-level document, not to individual resources like images or scripts. For modern browsers, also set `Content-Security-Policy: frame-ancestors 'self'` which provides the same protection with more flexibility.
How to fix it
Nginx
add_header X-Frame-Options "SAMEORIGIN" always; Apache
Header always set X-Frame-Options "SAMEORIGIN" Node.js / Express
const helmet = require('helmet');
app.use(helmet.frameguard({ action: 'sameorigin' })); Django
X_FRAME_OPTIONS = 'SAMEORIGIN' # or 'DENY'
# Django sets this by default via XFrameOptionsMiddleware Flask
@app.after_request
def set_headers(response):
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
return response Next.js
module.exports = {
async headers() {
return [{
source: '/(.*)',
headers: [{ key: 'X-Frame-Options', value: 'SAMEORIGIN' }]
}];
}
}; Spring Boot
http.headers().frameOptions().sameOrigin();
// or http.headers().frameOptions().deny(); References
- MDN: X-Frame-Options
- OWASP: Clickjacking Defense Cheat Sheet
- RFC 7034: HTTP Header Field X-Frame-Options
AppVet checks X-Frame-Options automatically
Run a free security scan and get a full report with actionable fixes, including a Fix with AI prompt you can paste into any coding tool.
Run Audit