Clickjacking Prevention
clickjacking prevention clickjacking prevention css complements frame-ancestors csp and x-frame-options — using frame-busting fallbacks (legacy), ui overlap audits, pointer-events discipline,
Introduction
Clickjacking prevention CSS complements frame-ancestors CSP and X-Frame-Options — using frame-busting fallbacks (legacy), UI overlap audits, pointer-events discipline, and visible iframe boundaries so users cannot be tricked into clicking hidden actions.
Business problem
Clickjacking embeds your site in attacker iframe with opacity 0.001 overlaying decoy buttons — user thinks they click "Win prize" but authorizes bank transfer. Likejacking on social widgets caused widespread awareness.
- Legal: Financial and auth flows must resist UI redress.
- Reputation: Users blame victim site not attacker frame.
Why this feature exists
frame-ancestors CSP (and legacy X-Frame-Options DENY/SAMEORIGIN) tells browser refuse embedding — primary defense. CSS frame-busting (position:fixed on body) unreliable — removed from modern guidance but taught historically.
- Double defense: CSP header + layout audit ensuring no self-inflicted overlays on own site.
- Same-origin: Attacker needs embed OR same-page overlay — both threat modes.
Browser rendering perspective
Embedded page in iframe still renders fully — attacker CSS on parent scales iframe to 1px or positions off-screen while showing decoy. frame-ancestors blocks embed entirely in modern browsers.
- Opacity: iframe element opacity <1 still clickable unless pointer-events:none.
Internal browser workflow
Prevention stack: 1) CSP frame-ancestors 'none' on sensitive routes 2) X-Frame-Options for legacy 3) QA CSS audit — no opaque overlays on action buttons 4) SameSite cookies limit CSRF companion risk 5) Confirm sensitive actions need re-auth.
Feature deep dive
Clickjacking defenses:
/* HTTP headers — primary */Content-Security-Policy: frame-ancestors 'none';X-Frame-Options: DENY/* On your own site — prevent self-clickjack overlays */.checkout-confirm-btn {position: relative;z-index: var(--z-action, 50);}/* Audit: no fixed promo z-index: 9999 over confirm *//* ❌ Legacy unreliable */body { display: block; } /* frame-busting JS removed — use CSP */
Syntax
Allow partner embed only:
Content-Security-Policy: frame-ancestors 'self' https://trusted.partner.com;
Examples
Facebook Like button era: invisible iframe over content — led to X-Frame-Options defaults and CSP adoption on auth pages.
Real-world use
OWASP Clickjacking Defense Cheat Sheet — frame-ancestors first. Banking regulators test embed resistance. Shopify admin denies framing.
Real production example
Global security headers middleware — frame-ancestors on all routes except explicit embeddable widget endpoint with partner allowlist.
Enterprise use case
Pen test includes clickjacking PoC on transfer and admin delete actions annually.
Accessibility considerations
Overlays break keyboard and SR — fixing clickjacking overlaps often fixes a11y focus obscured too.
Performance considerations
N/A — CSP headers zero runtime cost.
SEO considerations
frame-ancestors doesn't affect SEO crawl — Googlebot doesn't frame pages.
Scalability considerations
Partner embed program — narrow allowlist path /embed/* with separate CSP template.
Common production issues
Incidents: Missing frame-ancestors on new microservice admin UI — embedded in phishing site within 48h of launch. Internal tool allowed SAMEORIGIN — attacker subdomain embed.
Debugging guide
Test embed: Local HTML iframe src=your-app — should refuse to render. curl -I check headers on all environments including CDN.
Best practices
- frame-ancestors 'none' default; allowlist only where required.
- X-Frame-Options DENY for legacy browsers on sensitive apps.
- Z-index audit on pages with confirm/delete actions.
- Pen test clickjacking annually.
- Never rely on CSS/JS frame-busters alone.
Anti-patterns
- Missing CSP on new SPA routes after migration.
- ALLOWALL or permissive frame-ancestors *.
- Fixed marketing overlays covering primary CTA without pointer-events fix.
Trade-offs
- Benefit: frame-ancestors is robust modern fix.
- Cost: Breaks legitimate embed use cases — partner allowlist maintenance.
Architecture review questions
- frame-ancestors on auth, checkout, admin?
- Pen test embed PoC attempted recently?
- Any overlay z-index above confirm buttons?
Interview questions
Defense layers against clickjacking?(Advanced)
Primary: CSP frame-ancestors and X-Frame-Options deny untrusted embed. Secondary: on own site prevent overlay CSS z-index bugs on sensitive buttons. Tertiary: re-auth for sensitive actions. Don't rely on JS frame busting.
Follow-up: When allow partner embed?
Hands-on exercise
Exercise: Attempt iframe embed of local app; add frame-ancestors; build overlay clickjack on own page; fix z-index; retest.
Staff engineer notes
- New routes need headers middleware checklist — easy miss on SPA splits.
Common pitfalls
- CDN stripping security headers on static HTML shell.
Try it yourself
Edit the CSS panel — the preview updates live. Use DevTools Performance and Accessibility panels to validate.
Try it yourself
Summary
Clickjacking prevention combines CSP frame-ancestors, X-Frame-Options, z-index overlay audits, and pen testing — CSS layout discipline ensures no self-inflicted UI redress on sensitive actions.
Key takeaways
- frame-ancestors CSP is primary clickjacking defense.
- Audit z-index overlays on confirm/auth buttons.
- Don't rely on legacy CSS/JS frame busters.