TL;DR
The X-Frame Options header is a security measure to prevent clickjacking attacks. However, it’s not foolproof and can be bypassed in certain situations. This guide explains common bypass techniques and how to mitigate them.
Understanding X-Frame Options
X-Frame Options tells the browser whether or not a page can be displayed inside an <frame>, <iframe>, or <object>. There are three main directives:
- DENY: The page cannot be displayed in a frame, regardless of the site attempting to do so.
- SAMEORIGIN: The page can only be displayed in a frame on the same origin as itself (same protocol, domain and port). This is the most common setting.
- ALLOW-FROM uri: The page can only be displayed in a frame from the specified URI. Note: this directive is deprecated due to security concerns and isn’t supported by all browsers.
Bypass Techniques
- Browser Compatibility Issues: Older browsers may not fully respect the X-Frame Options header, or have different interpretations. This is becoming less common but still possible. Testing across multiple browser versions is important.
- JavaScript Frame Breaking: JavaScript can attempt to break out of a frame if it detects it’s been framed. While not a direct bypass, it can disrupt clickjacking attempts.
if (top != self) { top.location.href = self.location.href; }However, this is easily defeated by attackers controlling the frame content or using techniques to prevent script execution.
- HTML5 History API: If a site uses the HTML5 History API (
pushState,replaceState), an attacker might be able to manipulate the URL within the frame to redirect the user after clickjacking.history.pushState({}, '', '/safe-page'); // Example of using pushState - Double Framing: An attacker can use multiple nested frames. The outer frame might be from a different origin, but the inner frame contains the target page.
This relies on browser inconsistencies in how they handle nested frames and X-Frame Options.
- CSP (Content Security Policy) Misconfiguration: A weak or missing CSP can allow framing even if X-Frame Options is set. Check your CSP header carefully.
Content-Security-Policy: frame-ancestors 'self'This allows framing only from the same origin. A more permissive policy like
frame-ancestors *would allow framing from any origin, effectively negating X-Frame Options. - Server-Side Frame Breaking (Redirects): If a server detects it’s being framed by an untrusted source, it can redirect the user to a safe page.
This requires server-side logic and is more reliable than JavaScript frame breaking.
Mitigation Strategies
- Use
X-Frame-Options: DENYwhenever possible. This provides the strongest protection, but may break legitimate use cases (e.g., embedding content in your own site). - If you need to allow framing from your own domain, use
X-Frame-Options: SAMEORIGIN. - Implement a strong Content Security Policy (CSP) with a restrictive
frame-ancestorsdirective. This is the most effective defense.Content-Security-Policy: frame-ancestors 'self' *.yourdomain.com;This allows framing from your own domain and any subdomains.
- Regularly audit your website for potential X-Frame Options bypass vulnerabilities. Use security scanning tools and manual testing.
- Consider using a web application firewall (WAF) to detect and block clickjacking attempts.
- Educate developers about the risks of clickjacking and how to properly configure X-Frame Options and CSP.
cyber security Best Practices
Remember that X-Frame Options is just one layer of defense against clickjacking attacks. A comprehensive cyber security strategy should include multiple layers of protection, such as input validation, output encoding, and regular security audits.

