CSP frame-ancestors vs X-Frame-Options
Understanding X-Frame-Options
X-Frame-Options is an HTTP response header that allows you to control whether a browser should be allowed to render a page in a<frame>
, <iframe>
, <embed>
or <object>
. This helps avoid clickjacking attacks.
Available Values
- DENY: Prevents any domain from framing the content
- SAMEORIGIN: Allows framing only by pages on the same origin
- ALLOW-FROM origin (Deprecated): Allowed framing by specific domains (no longer supported by modern browsers)
Example of X-Frame-Options header
X-Frame-Options "DENY";
Implementation in different web servers:
Nginx
Add to your server block:Example of X-Frame-Options header on Nginx
add_header X-Frame-Options "DENY";
Apache
Add to your .htaccess or configuration:Example of X-Frame-Options header on Apache
Header set X-Frame-Options "DENY"
Next.js
Add to your next.config.js:Example of X-Frame-Options header in Next.js
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'X-Frame-Options',
value: 'DENY'
}
]
}
]
}
}
CSP frame-ancestors Directive
The frame-ancestors directive is part of Content Security Policy and provides more granular control over who can embed your content. Learn more about Content Security PolicyDirective Values
- 'none': Prevents any embedding
- 'self': Allows embedding only from the same origin
- URI/Domain: Allows embedding from specific sources
Example of frame-ancestors directive
Content-Security-Policy: frame-ancestors 'self' https://trusted.com;
Meta Tag Limitation
The frame-ancestors directive is not supported in meta tags. It must be set via HTTP header.
Header Priority in Modern Browsers
When both X-Frame-Options and frame-ancestors are present, modern browsers will prioritize the frame-ancestors directive and ignore X-Frame-Options completely.Example of conflicting header policies
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors https://allowed-domain.com;
Browser Behavior
In this example, modern browsers will allow framing from allowed-domain.com, completely ignoring the DENY from X-Frame-Options.
• Modern Browsers :
• Legacy Browsers
Important Note
Due to this priority behavior, ensure your frame-ancestors directive is at least as restrictive as your X-Frame-Options header to maintain security across all browsers.
Comparing Both Approaches
X-Frame-Options
Simple to implement but limited in functionality
- Only supports one domain with ALLOW-FROM (deprecated)
- Limited browser support for some features
frame-ancestors
More flexible and powerful, with better browser support
- Supports multiple domains
- Widely supported in modern browsers
- Provides more granular control
Best Practices
Implementation Guidelines
Follow these best practices to ensure maximum security and compatibility across browsers.
- Use both headers for maximum compatibility
- Prefer frame-ancestors for modern browsers
- Use DENY by default unless embedding is required
- Regularly audit allowed domains
Example of using both headers for maximum protection & compatibility
Content-Security-Policy: frame-ancestors 'none';
X-Frame-Options: DENY
Recommendation
While using both headers provides the best coverage, frame-ancestors is the modern standard and should be your primary method of control.
Common Use Cases
- Public Content : Use 'none' to prevent any framing
- Internal Tools : Use 'self' to allow same-origin framing
- Partner Integration : Specify allowed partner domains
Conclusion
While X-Frame-Options provides basic protection against clickjacking, the CSP frame-ancestors directive offers more flexibility and better browser support. Using both headers ensures maximum compatibility across browsers while providing robust protection against framing-based attacks.
Continue Reading
JSONP and Content Security Policy
Learn what is the JsonP endpoint and what is the impact of using it with CSP. See how to avoid using JSONP endpoint and how it can be used to bypass CSP.

Stay safe, no more unsafe-inline
Learn more about unsafe-inline and how to properly setup your CSP to avoid using it.
