X-XSS-Protection: a legacy header and why it is off
X-XSS-Protection controlled a built in browser filter that tried to detect reflected cross-site scripting. Modern browsers removed the filter, and current advice is to send 0 or nothing.
At a glance
- Direction
- Response only. It is non-standard and was never in an RFC.
- Defined in
- Non-standard. Removed from Chrome and Edge, never implemented in Firefox.
- When absent
- Nothing happens in current browsers, because the filter it controlled no longer exists.
- Values
- 0 disables the filter, 1 enables it, 1; mode=block enables it and blocks the page.
- Status
- Legacy. It has no effect in current Chrome, Edge or Firefox.
- Replacement
- Content-Security-Policy, plus contextual output encoding in the application
- In the headers checker
- Reported and labelled legacy. It is not one of the six headers that affect the grade.
In detail
The auditor compared the request query string with the response body and, when a fragment appeared in both, tried to neutralise it. It was a heuristic, and heuristics that rewrite pages create their own problems: researchers demonstrated ways to use the filter to remove parts of a page deliberately, turning a defensive feature into a way to disable other defences.
Chrome removed the auditor in 2019, Edge followed after moving to the same engine, and Firefox never shipped one. Safari retains a similar filter, which is the only reason the header is still discussed at all. Sending 1; mode=block today therefore changes behaviour in at most one browser and none of the others.
Because the enabled mode could be abused, the value most guidance now recommends is 0, explicitly turning the filter off where it still exists. That is a real reversal from advice written before 2019, which is why older checklists and current ones disagree so sharply about this one header.
What actually replaces it is a Content-Security-Policy that forbids inline script, plus encoding output for the context it lands in. Neither depends on guessing whether a fragment of the request looks dangerous, which was the assumption the auditor was built on, and both work on stored injection as well as reflected injection, which the filter never addressed at all.
If a compliance document requires the header, sending 0 satisfies the requirement to have a value while matching current guidance, and it is worth attaching that reasoning to the exception rather than arguing it again at the next audit. The header costs nothing either way; what matters is whether a real policy sits alongside it.
Examples
X-XSS-Protection: 0X-XSS-Protection: 1; mode=blockThis has no effect in Chrome, Edge or Firefox, and it is the mode shown to be abusable where it does still run.
Things that catch people out
- Security scanners still flag a missing X-XSS-Protection header, which pushes teams to add a value current browsers ignore. Check whether the finding is based on guidance written before 2019.
- The header is no substitute for a CSP. A site with X-XSS-Protection and no CSP has no meaningful protection against injected script.
- Do not confuse it with X-Content-Type-Options. That one is current, standardised and worth sending.
Try it: HTTP Headers Checker
Check a live URL or paste headers you already have. It grades six security headers from A+ to F and lists every other header the response returned.
HTTP Headers Checker
LOCAL · Browser-OnlyView HTTP response headers for any URL
Enter any website URL to fetch and analyze its HTTP response headers. We'll automatically add https:// if needed.
Why Check Security Headers?
Security headers protect your website against common attacks like XSS, clickjacking, and MIME sniffing. They're set by your web server and cost nothing to implement. Missing security headers are one of the most common findings in security audits.
Related HTTP headers
All http headers →Content-Security-Policy: directives, sources and reporting
How CSP directives are matched, what default-src actually falls back to, why unsafe-inline defeats the point of a policy, and how nonces and hashes work.
X-Content-Type-Options: nosniff and MIME sniffing
What nosniff stops a browser doing, why it is the safest security header to add, and the two kinds of resource it starts rejecting once you turn it on.
X-Frame-Options: DENY, SAMEORIGIN and clickjacking
What DENY and SAMEORIGIN do, why ALLOW-FROM never worked, and how CSP frame-ancestors supersedes this header while it is still worth sending.
Content-Security-Policy-Report-Only: testing a policy safely
How the report-only CSP header measures a policy without blocking anything, where the violation reports go, and when to run it alongside an enforcing policy.
Cross-Origin-Opener-Policy: isolating your browsing context
What COOP severs between your page and the windows it opens, how same-origin differs from same-origin-allow-popups, and its part in cross-origin isolation.
Cross-Origin-Embedder-Policy: require-corp and credentialless
What require-corp demands from every subresource, how credentialless relaxes it, and why enabling COEP is what breaks third party images and embeds.
Tools for this
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body