Home / Fix guides / Clickjacking protection
Prevent clickjacking: X-Frame-Options and frame-ancestors
Medium
Your pages can be embedded in an iframe on any website. Attackers can overlay your app invisibly and trick logged-in users into clicking 'delete', 'pay' or 'share'.
Why it matters
Clickjacking needs no bug in your code, just a missing header.
Quick fix
- Add X-Frame-Options: DENY (or SAMEORIGIN if you embed yourself).
- Or add frame-ancestors 'none' to your Content-Security-Policy.
Step by step
Add the header
Use your platform's header config:
// vercel.json (works for Vite/React apps deployed on Vercel)
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" },
{ "key": "Content-Security-Policy", "value": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://*.supabase.co wss://*.supabase.co; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" }
]
}
]
}Prompt for your AI builder
Paste this into Lovable, Bolt, v0, Cursor or Replit, then review the changes before deploying.
Add X-Frame-Options: DENY and a CSP frame-ancestors 'none' directive to every response of my app using my hosting platform's header configuration.References
- OWASP: Clickjacking Defense Cheat Sheet
- Vercel docs: custom headers
- Next.js docs: headers()
- Netlify docs: custom headers