X-Frame-Options and Clickjacking Protection
How framing controls prevent attackers from tricking users into interacting with an invisible, embedded page.
Core Concept
Clickjacking tricks users into clicking something different from what they perceive, typically by overlaying an invisible iframe of a legitimate site beneath deceptive content.
X-Frame-Options and its modern successor, the frame-ancestors CSP directive, prevent a page from being embedded in a frame on another site at all.
X-Frame-Options Values
The header supports a small, fixed set of values controlling where framing is permitted.
- DENY — page cannot be framed by any site, including itself
- SAMEORIGIN — page can only be framed by pages on the same origin
- ALLOW-FROM (deprecated) — previously allowed a specific origin
Deprecated but Present
X-Frame-Options is technically superseded by CSP's frame-ancestors directive, but remains widely deployed for compatibility with older browsers.
The Modern Alternative: frame-ancestors
CSP's frame-ancestors directive offers more flexibility than X-Frame-Options, supporting multiple allowed origins rather than a single value.
- frame-ancestors 'none' — equivalent to DENY
- frame-ancestors 'self' — equivalent to SAMEORIGIN
- frame-ancestors can list multiple specific trusted origins
Why Some Sites Need Framing Enabled
Not every site should block framing outright — legitimate embedding use cases exist and need to be explicitly accounted for.
Widgets, embedded payment forms, and single sign-on flows often rely on controlled framing between trusted, specifically listed origins.
Allowlisting Over Blanket Denial
Rather than disabling framing protection entirely, sites with legitimate embedding needs should allowlist specific trusted origins.
Verifying Protection Is Effective
A quick audit confirms clickjacking protection is actually working as intended.
- Header present on every page, not just the homepage
- Value matches the site's actual embedding requirements
- CSP frame-ancestors and X-Frame-Options are consistent with each other
Real-World Implementation
Clickjacking protection is now a baseline expectation for any page handling sensitive actions.
- Banking and authentication pages using DENY
- SaaS platforms allowlisting specific partner embed origins
- Security scanners flagging missing framing headers as a standard check
Framing protection is inexpensive to implement and closes off an entire class of UI-redress attacks with a single, simple header.
Common Mistakes to Avoid
A few common mistakes leave clickjacking protection incomplete.
- Applying framing protection only to the homepage instead of every sensitive page.
- Setting inconsistent values between X-Frame-Options and CSP's frame-ancestors.
- Disabling framing protection entirely instead of allowlisting specific trusted origins.
- Assuming X-Frame-Options alone is sufficient without considering the modern CSP alternative.
- Overlooking legitimate embedding needs, like widgets, when hardening framing policy.
- Overlooking that some legacy browsers only respect X-Frame-Options, not frame-ancestors.
- Assuming clickjacking protection is unnecessary for pages without sensitive actions.
- Failing to test framing behavior after any significant page redesign.
- Overlooking that some analytics or A/B testing tools rely on legitimate framing.
- Assuming clickjacking protection headers work identically across all embedded contexts.
- Failing to verify framing protection specifically after adding a new third-party widget.
- Overlooking that some older embed-dependent widgets may break entirely under strict framing protection.
Best Practices Checklist
These practices ensure clickjacking protection is applied consistently and correctly.
- Apply framing protection consistently across every page, not just the homepage.
- Keep X-Frame-Options and CSP's frame-ancestors values consistent with each other.
- Allowlist specific trusted origins rather than disabling protection entirely for embedding needs.
- Prioritize CSP's frame-ancestors as the modern standard where supported.
- Test framing behavior directly rather than assuming header configuration alone guarantees protection.
- Maintain both X-Frame-Options and frame-ancestors together for broader browser compatibility.
- Apply framing protection consistently across all pages, not just obviously sensitive ones.
- Re-test framing behavior after significant page redesigns or embed feature changes.
- Check whether analytics or A/B testing tools depend on framing before applying strict protection.
- Test framing protection behavior across the different embedding contexts actually in use.
- Verify framing protection remains correctly configured after adding any new third-party widget.
- Test all embed-dependent widgets thoroughly before applying the strictest framing protection setting.
Frequently Asked Questions
Frequently asked questions about X-Frame-Options and clickjacking.
What is a clickjacking attack?
It tricks users into clicking something different from what they perceive, typically through an invisible iframe of a legitimate site overlaid beneath deceptive content.
What's the difference between X-Frame-Options and CSP's frame-ancestors?
frame-ancestors is the modern CSP-based replacement, offering more flexibility by supporting multiple allowed origins rather than a single value.
Which value takes priority if both headers are present?
Browsers that support CSP's frame-ancestors will generally prioritize it over X-Frame-Options, so the two should be kept consistent.
Do all sites need to block framing entirely?
No — sites with legitimate embedding needs, like widgets or payment forms, should allowlist specific trusted origins instead of blocking outright.
Is clickjacking protection only relevant to login pages?
It matters for any page handling sensitive actions, not just login forms — anywhere a misleading click could cause real harm.
Why maintain both X-Frame-Options and frame-ancestors?
Because some legacy browsers only respect the older X-Frame-Options header, so keeping both maximizes overall compatibility.
Do pages without sensitive actions still need clickjacking protection?
Generally yes — inconsistent protection across a site leaves the unprotected pages just as exposed as if none existed at all.
Should framing behavior be retested after a redesign?
Yes — layout or embed feature changes can inadvertently alter framing requirements, making retesting a worthwhile step.
Do any legitimate tools rely on being framed?
Some analytics or testing tools can, making it worth checking dependencies before applying maximally strict clickjacking protection.
Should protection be re-verified after adding a new widget?
Yes — a new third-party integration can sometimes require framing that conflicts with existing protection settings.
Can strict framing protection break legitimate widgets?
Yes — some older widgets rely on being embedded elsewhere, so strict protection should be tested carefully before full deployment.
Check Clickjacking Protection
Run a security headers scan to verify a domain's framing protection configuration.
Launch Tool →