How to set X-Frame-Options correctly?
x-frame-options-incorrectpage
X-Frame-Options controls iframe embedding at the HTTP header level. The header accepts three values: DENY prohibits all framing, SAMEORIGIN allows same-origin framing, and ALLOW-FROM specifies a single allowed origin. Incorrect values or missing headers permit unauthorized embedding that enables clickjacking attacks.
What’s wrong
The X-Frame-Options header is missing, set to an invalid value, or uses ALLOW-FROM which lacks broad browser support. Without a valid header, browsers permit embedding from any origin. ALLOW-FROM appears functional but modern browsers ignore it. Invalid syntax provides no protection while creating the appearance of security.
Why it matters
Frame embedding creates clickjacking opportunities. An attacker embeds a page in a transparent iframe over misleading interface elements. Users click what they see on the malicious page but actually interact with the embedded page. The embedded page processes authenticated actions because session state is valid. Missing or incorrect X-Frame-Options leaves pages vulnerable to this interface manipulation.
The correct change
Set X-Frame-Options to DENY or SAMEORIGIN. Use DENY for pages that should never appear in frames, including login pages and sensitive operations. Use SAMEORIGIN for pages that may need same-origin embedding while blocking cross-origin framing. Avoid ALLOW-FROM due to limited browser support. The end state is a valid header value that browsers enforce to prevent unauthorized embedding.
Scope
This condition applies at the page level. Each response can set its own X-Frame-Options value. Global configuration typically applies the same policy across all pages. Sensitive pages benefit from DENY while content pages may use SAMEORIGIN if same-origin embedding exists.
How to verify
- Validation confirms the condition is resolved:
- • X-Frame-Options header present in response
- • Header value is DENY or SAMEORIGIN
- • No ALLOW-FROM values in production configurations
- • Browser blocks cross-origin framing attempts when DENY is set
- • Same-origin framing works when SAMEORIGIN is set
- • Cross-origin framing fails when SAMEORIGIN is set
- • Security scanners confirm clickjacking protection is active
Takeaway
- X-Frame-Options has only two reliable values: DENY and SAMEORIGIN
- DENY prevents all framing, SAMEORIGIN allows same-origin embedding only
- ALLOW-FROM has poor browser support and should not be used
- Content Security Policy frame-ancestors provides more flexibility for complex cases
FAQ
Should most pages use DENY or SAMEORIGIN?
DENY unless same-origin framing is required. Most pages never need iframe embedding. Login pages, account management, and sensitive operations should always use DENY. Content pages can use SAMEORIGIN if the application legitimately embeds its own pages.
Why does ALLOW-FROM not work reliably?
Browser support was always limited and most browsers now ignore it. Chrome never fully implemented ALLOW-FROM. Firefox and Edge removed support. The directive provides no functional protection in modern browsers. Use CSP frame-ancestors for equivalent functionality with broad support.
Can X-Frame-Options and frame-ancestors coexist?
Yes. Set both for defense in depth and backward compatibility. Modern browsers prioritize frame-ancestors when both are present. Older browsers that lack CSP support still respect X-Frame-Options. Consistent values across both headers prevent confusion.
Does X-Frame-Options affect window.open or popups?
No. The header controls only iframe, frame, and object embedding. Window.open creates new top-level contexts that are not affected. Popups and new windows do not inherit or respect X-Frame-Options from the opener.
What breaks when DENY is set but pages are embedded?
Legitimate iframe embedding stops working. Third-party integrations that embed pages fail. OAuth flows using iframes break. Internal applications that frame content stop functioning. Audit embedding requirements before deploying DENY globally. Sensitive pages should use DENY regardless.
Should static assets set X-Frame-Options?
Not typically necessary. Clickjacking targets interactive pages where user actions matter. Images, scripts, and stylesheets do not process user actions. Focus X-Frame-Options on HTML pages, especially those requiring authentication. Static assets can omit the header without security impact.
The fix
Prevent clickjacking by correctly setting X-Frame-Options to control frame embedding
Done when: X-Frame-Options is set to DENY or SAMEORIGIN on all interactive pages, preventing unauthorized iframe embedding
Do not
- Do not use ALLOW-FROM due to lack of browser support
- Do not use invalid values or custom strings that browsers ignore
- Do not omit the header on sensitive pages assuming clickjacking is unlikely
- Do not set SAMEORIGIN when no legitimate same-origin framing exists
How to verify
- X-Frame-Options header present with DENY or SAMEORIGIN
- No ALLOW-FROM values in configuration
- Browser blocks unauthorized framing based on policy
- Same-origin framing behaves according to policy
- Security scanners confirm clickjacking protection
Find every page with this
probeo monitors this continuously across every page of your site, and records which pages passed, which failed, and which it could not determine.
Book a Call