Validates X-Frame-Options header for clickjacking protection
3 of 3 free audits left today
See what X-Frame-Options finds on your site. No sign-up needed.
Fetch β sends a HEAD request (or GET when HEAD is not supported) to the audited URL as 37AuditsBot. A blocked request ends the audit with 590; any other failure (timeout, DNS, TLS, non-2xx answer) ends it with 500.
CSP first β when an enforced Content-Security-Policy header (not Content-Security-Policy-Report-Only) has a frame-ancestors directive, browsers ignore X-Frame-Options, so the page passes. A frame-ancestors * alone allows every site and does not count.
Read β like browsers, collects every X-Frame-Options header line, splits it on commas, trims and lowercases each value and drops duplicates. DENY, DENY is read as deny.
Rules β a missing header (400), the obsolete ALLOW-FROM (401) and any other value that is not DENY or SAMEORIGIN, such as ALLOWALL (402), fail. Several distinct values that include DENY, SAMEORIGIN or ALLOWALL warn (300): browsers then block every frame.
Aggregate β FAIL wins over WARNING; when every rule passes the audit is SUCCESS (200).
Specification pin β every run emits 37A-XFrameOptionsAuditor-100 (INFORMATION), naming the X-Frame-Options section of the WHATWG HTML Living Standard as of 2026-10-15. It does not change the overall status.
Every row maps to one checkRule* method and one CheckCode, in the order the auditor runs them. CheckCode suffixes use status ranges: 100 information, 200 success, 300β399 warning, 400β499 fail, 500β599 error.
| CheckCode | Status | When it fires | Recommendation | Why it matters |
|---|---|---|---|---|
37A-XFrameOptionsAuditor-100 | INFORMATION | Always. Records the specification version this auditor implements. | β (recommendation is null; nothing for the site to change) | β |
37A-XFrameOptionsAuditor-400 | FAIL | The page sends no X-Frame-Options value and no CSP frame-ancestors. | Add "X-Frame-Options: SAMEORIGIN" (or DENY) or "Content-Security-Policy: frame-ancestors 'self'" to the responses of {url}. | Without frame protection, attackers can load your site in a hidden frame and trick visitors into clicking buttons they cannot see (clickjacking). |
37A-XFrameOptionsAuditor-401 | FAIL | Every X-Frame-Options value is ALLOW-FROM β¦, which current browsers ignore. | Replace "{value}" with "Content-Security-Policy: frame-ancestors 'self' {origin}" to allow only {origin}. | Browsers dropped ALLOW-FROM, so the page has no frame protection and is open to clickjacking. |
37A-XFrameOptionsAuditor-402 | FAIL | The value is not DENY or SAMEORIGIN (for example ALLOWALL or a typo), so browsers ignore it. | Replace "{value}" with "SAMEORIGIN" or "DENY" in the X-Frame-Options header of {url}. | Browsers ignore this value, so the page is as exposed to clickjacking as if the header were missing. |
37A-XFrameOptionsAuditor-300 | WARNING | The header carries several distinct values that include DENY, SAMEORIGIN or ALLOWALL. | Send a single value ("SAMEORIGIN" or "DENY") instead of "{value}" on {url}; check for a duplicate header added by the server and a proxy or CDN. | Conflicting values usually mean two layers set the header; browsers then block all framing, which can break your own embedded pages. |
37A-XFrameOptionsAuditor-200 | SUCCESS | All rules passed. Message names the X-Frame-Options value or the CSP frame-ancestors sources that protect the page. | β | β |
37A-XFrameOptionsAuditor-500 | ERROR | The page could not be fetched (timeout, DNS, TLS, or a non-2xx answer other than a block). | Make sure {url} answers with HTTP 2xx, then run the audit again. Last error: {error}. | β |
37A-XFrameOptionsAuditor-590 | ERROR | The audited page answered HTTP 403, HTTP 429 or a Cloudflare challenge, so 37AuditsBot was blocked before it could read the page. | Allow 37AuditsBot in your firewall or bot protection: allowlist its user agent, or verify its Web Bot Auth signature. See https://www.37audits.com/bot. | While 37AuditsBot is blocked this audit cannot look at the site, so problems on it go unreported. |
| Status | Description | Test logic |
|---|---|---|
| SUCCESS | Other sites cannot frame this page | X-Frame-Options is DENY or SAMEORIGIN (any letter case), or an enforced CSP has a restricting frame-ancestors (200). |
| WARNING | Framing is blocked, including your own pages | Conflicting X-Frame-Options values (300). |
| FAIL | Any site can frame this page | Missing header (400); ALLOW-FROM (401); any other value that is not DENY or SAMEORIGIN (402). |
| ERROR | The auditor could not read the page | Fetch failure or non-2xx answer (500); site blocked 37AuditsBot (590). |
| INFORMATION | Specification pin | Always emitted (100); does not change overall status. |
Any page where a single click does something (buy, delete, transfer, share, change a password or a permission) can be abused while it sits in a hidden frame on another site.
Login and account pages are the most valuable targets, but the protection is cheap enough to send on every page.
DENY forbids every frame; SAMEORIGIN allows only pages of your own origin.
ALLOW-FROM was never supported by Chrome or Safari and Firefox dropped it, so it gives no protection. To allow specific partner sites, use Content-Security-Policy: frame-ancestors 'self' https://partner.example.
When frame-ancestors is present, browsers ignore X-Frame-Options. Many sites send both so older browsers stay protected.
A web server and a CDN or proxy that both add the header produce values such as SAMEORIGIN, DENY. Browsers treat that as a conflict and refuse every frame, which can break pages you embed yourself.
Only the audited URL is fetched; other pages of the site may be sent without the header.
Content-Security-Policy set in an HTML <meta> tag is not read: browsers ignore frame-ancestors there.
The sources listed in frame-ancestors are not judged, apart from a lone *.
This documentation is built and hosted on Mintlify, a developer documentation platform.
Add this auditor to your monitoring setup and start identifying issues on your websites today.