Medium severity

How to fix a missing X-Frame-Options header (clickjacking protection)

Your site is missing X-Frame-Options (or CSP frame-ancestors), which means any other site can embed yours in an iframe. Attackers use this for clickjacking — overlaying an invisible copy of your site on a decoy page so users unknowingly click buttons on your app. Fix it with one of two headers: `X-Frame-Options: DENY` (blocks all iframe embedding) or the modern equivalent `Content-Security-Policy: frame-ancestors 'none'`. If you need to allow embedding on specific domains, use `frame-ancestors` with a list.

Why it matters

Clickjacking is especially dangerous for apps with one-click destructive actions — subscribe, pay, share, delete. An attacker can make users perform these without realizing. Browsers no longer display a warning when a site is framed.

How to check

  1. 01Check the Response Headers for `x-frame-options` or `content-security-policy` with `frame-ancestors`.
  2. 02Try embedding your site: create an HTML file with `<iframe src="https://your-site.com"></iframe>` and open it in a browser.
  3. 03If the iframe renders your page, you are vulnerable.

Or let SafeToShip check it for you in 60 seconds:

How to fix it

Next.js

Add both headers for belt-and-suspenders protection.

headers: [
  { key: 'X-Frame-Options', value: 'DENY' },
  { key: 'Content-Security-Policy', value: "frame-ancestors 'none'" }
]

Generic

Send both headers on every HTML response.

X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'

AI prompt

Copy-paste into your AI tool

Paste this prompt into Cursor, Lovable, Bolt, v0, or Claude Code and it will walk through the fix for your specific codebase.

Add X-Frame-Options: DENY to my app, plus a Content-Security-Policy header with frame-ancestors 'none'. If I already have a CSP header, merge the frame-ancestors directive into it. Apply to all routes.

FAQ

Frequently asked questions

What if I want to embed my own app in a subdomain?
Use `frame-ancestors 'self'` or list specific domains: `frame-ancestors 'self' https://app.example.com`. `DENY` blocks all embedding, including from your own site.
Is X-Frame-Options deprecated?
Modern browsers prefer CSP `frame-ancestors`, but X-Frame-Options still works and some older browsers only respect that one. Ship both; they do not conflict.
Do SameSite cookies replace this?
No. SameSite protects against CSRF by blocking third-party cookie use. Clickjacking does not need cookies — the attacker tricks the user into clicking while logged in normally. You need both.

Scan your site for this and 50+ other issues

Free scan. Results in 60 seconds. No account required.