Skip to main content

X-Frame-Options.

Security Headers & TLS Config

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

nginx
add_header X-Frame-Options "SAMEORIGIN" always;

Apache

apache
Header always set X-Frame-Options "SAMEORIGIN"

Node.js / Express

js
const helmet = require('helmet');
app.use(helmet.frameguard({ action: 'sameorigin' }));

Django

python
X_FRAME_OPTIONS = 'SAMEORIGIN'  # or 'DENY'
# Django sets this by default via XFrameOptionsMiddleware

Flask

python
@app.after_request
def set_headers(response):
    response.headers['X-Frame-Options'] = 'SAMEORIGIN'
    return response

Next.js

js
module.exports = {
  async headers() {
    return [{
      source: '/(.*)',
      headers: [{ key: 'X-Frame-Options', value: 'SAMEORIGIN' }]
    }];
  }
};

Spring Boot

java
http.headers().frameOptions().sameOrigin();
// or http.headers().frameOptions().deny();
Use `DENY` if your site is never intended to be framed. Pair this with `Content-Security-Policy: frame-ancestors 'self'` for the most robust protection. Test by attempting to iframe your site from a different domain.

References

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