X-XSS-Protection
Remove it, or send `X-XSS-Protection: 0`. No current browser implements the filter, and where it existed it introduced vulnerabilities of its own.
Obsolete. Current browsers ignore it, and the behaviour it requested was itself a problem.
What it does
X-XSS-Protection controlled a browser-side heuristic that tried to spot reflected cross-site scripting by comparing the request to the response. It was a reasonable idea in 2008 and a bad one by 2018: the filter could be induced to block legitimate content, and — more seriously — its `mode=block` behaviour and its selective neutering of script were themselves usable as attack primitives, including to read cross-origin data and to disable legitimate defences on a page.
Chrome removed its XSS Auditor in 2019. Edge removed its filter. Firefox never implemented one. The header today is inert in every browser a visitor is realistically using, which makes the argument about its correct value largely academic — but not entirely, because some compliance scanners and older proxies still flag its absence, and teams add it back to satisfy a report.
If a scanner demands the header, `0` is the correct value: it explicitly disables a filter that no longer exists rather than requesting one that was harmful. The actual defence against XSS is a Content-Security-Policy built on nonces, plus output encoding in the application. Neither is replaced by a header the browser ignores.
What to send
X-XSS-Protection: 0Send `0` only if something in your compliance process insists the header be present; otherwise remove it entirely. Never send `1; mode=block` — it requests a filter that is gone from current browsers and was exploitable in the ones that had it. The real control is CSP.
Directives and values
Disables the filter. The only value that is defensible today, and only because it is explicit about wanting the legacy behaviour off.
Enables the legacy filter in sanitising mode, where the browser rewrites what it believes is injected script. The rewriting itself was demonstrated to create vulnerabilities.
Enables the filter in blocking mode. Widely recommended for years, and the value behind several published attacks. Inert in current browsers.
Common mistakes
- Adding it back to satisfy a scanner. A scanner flagging its absence is checking against an outdated rule. If the finding must be closed, close it with `0` and a note, not with `1; mode=block`.
- Treating it as XSS protection. It never protected against stored or DOM-based XSS, only a subset of reflected cases, and it does not run at all now. A page relying on it has no XSS defence beyond whatever the application does itself.
- Leaving 1; mode=block in a legacy config. It is inert rather than dangerous in current browsers, but it is a reliable indicator that the rest of the security header configuration has not been reviewed in several years. Treat finding it as a prompt to audit the whole set.
Browser support
Removed from Chrome (2019) and Edge; never implemented in Firefox; Safari removed its equivalent. In practice no current browser acts on this header at all.
Frequently asked questions
Should I set X-XSS-Protection: 1; mode=block?
No. That value requests a browser filter that has been removed from every current browser, and in the browsers that did implement it the filter was itself exploitable. Either remove the header or send `0`.
Why was the XSS Auditor removed?
It caught only a subset of reflected XSS, produced false positives that broke legitimate pages, and its behaviour could be abused — attackers could use it to selectively disable scripts on a page or to infer cross-origin data. Chrome removed it in 2019 and other vendors followed or never shipped one.
What should I use instead of X-XSS-Protection?
A Content-Security-Policy based on per-response nonces with `strict-dynamic`, together with proper output encoding in the application. That combination addresses reflected, stored and DOM-based XSS, which the legacy filter never did.
My compliance scanner flags the missing header. What do I do?
Send `X-XSS-Protection: 0`. It satisfies a presence check while explicitly disabling the legacy filter rather than requesting it, and it is accurate about current browser behaviour.
The free Security Headers Checker reads X-XSS-Protection from a live response and grades it alongside every other header on this reference — no account needed.
For the longer treatment, read HTTP Security Headers: HSTS, CSP, X-Frame-Options & More in the Learning Center.
Related headers
The most powerful and most misconfigured security header. Most deployed policies provide no XSS protection at all.
One value, one line, no downside worth mentioning. Stops browsers second-guessing your Content-Type.
Blocks framing to prevent clickjacking. Superseded by CSP frame-ancestors, but still worth sending.