Skip to content

Missing X-Frame-Options Header

Severity: Medium

Last updated August 9, 2026.

What this finding means

Your site does not send an X-Frame-Options header, and no Content-Security-Policy frame-ancestors directive covers the same ground in its place. Browsers will therefore allow any other site to load your pages inside an iframe, which is the precondition for clickjacking attacks against anything on the page a user can click.

Why it matters

Without it, an attacker can embed your login page, payment form, or admin panel inside an invisible or disguised iframe on a malicious site and trick users into clicking buttons that actually act on your page — a clickjacking attack. This is especially relevant for any page with a state-changing action (login, delete, confirm, pay) that only requires a click.

What Nivaronix checks

Nivaronix's security headers checker inspects the response headers your site sends and reports whether framing is restricted at all. This is a security misconfiguration check based on the headers' presence and configuration — not a vulnerability scan, exploit attempt, or penetration test.

The check does read your Content-Security-Policy. Every current browser engine ignores X-Frame-Options outright when an enforced CSP declares frame-ancestors, so judging one header without the other would report a control as missing on a site that is protected. Three outcomes follow from that:

  • X-Frame-Options is absent but an enforced CSP declares a restrictive frame-ancestors — including frame-ancestors 'none', 'self', or a named origin or host wildcard: this finding is not reported. Your site is protected, and this pairing is what our own security-headers guide tells readers to deploy.
  • X-Frame-Options is absent and frame-ancestors is permissive — its whole source list is * or bare schemes such as https: — or absent entirely: this finding is reported. A directive that grants everyone is not protection.
  • X-Frame-Options is present but an enforced CSP declares a permissive frame-ancestors: a separate finding, X-Frame-Options overridden by a permissive CSP, is reported instead — because the header is not missing, and adding it again would not help.

What the check does not do is grade the rest of your policy. Only the frame-ancestors directive is read.

Evidence example

Example only, for illustration — not evidence from a live scan of any specific site.

HTTP/1.1 200 OK
(no X-Frame-Options header present)
(no Content-Security-Policy frame-ancestors directive either)

# also reported — frame-ancestors is present but grants everyone:
Content-Security-Policy: frame-ancestors *

# not reported — CSP restricts framing in X-Frame-Options' place:
Content-Security-Policy: frame-ancestors 'self'

How to fix it

Nginx

add_header X-Frame-Options "SAMEORIGIN" always;

Apache

Header always set X-Frame-Options "SAMEORIGIN"

Cloudflare

Rules → Transform Rules → Modify Response Header → set `X-Frame-Options` to `SAMEORIGIN` or `DENY`.

Verify the fix

Re-run a scan on your domain, or check manually with curl -sI https://your-domain.example, and confirm X-Frame-Options now appears in the response with the expected value.

FAQ

Why doesn't Nivaronix report this if my CSP already has frame-ancestors?

Every current browser engine ignores X-Frame-Options outright when an enforced Content-Security-Policy declares frame-ancestors, so a site with a restrictive frame-ancestors directive is already protected against clickjacking even with no X-Frame-Options header at all. Reporting it as missing in that case would flag a site that isn't actually vulnerable.

Should I set both X-Frame-Options and CSP frame-ancestors?

Setting frame-ancestors in an enforced CSP is sufficient on its own for any browser released in the last several years, since frame-ancestors takes precedence and X-Frame-Options is ignored once it's present. Adding X-Frame-Options alongside it only matters as a fallback for legacy browsers that don't support frame-ancestors — most sites don't need to carry both.

What's the practical difference between DENY and SAMEORIGIN?

DENY blocks the page from being framed by any site, including your own other pages. SAMEORIGIN allows framing only from pages on the exact same origin (scheme, host, and port). Most sites want SAMEORIGIN unless the page has no legitimate reason to ever be embedded anywhere, including internally.

Can clickjacking happen even with HTTPS and a valid certificate?

Yes — clickjacking is about the browser allowing your page to be loaded inside another site's iframe and tricking a user into clicking something they can't see, which is unrelated to whether the connection itself is encrypted or the certificate is valid. TLS protects the data in transit; framing protection is a separate control against a different attack.

Standards reference

MDN — X-Frame-Options. See the methodology page for exactly how this finding is scored.