X-XSS-Protection (deprecated)
Controlled the XSS auditor that old browsers ran. No current browser has that auditor, so the header does nothing useful today.
Updated 3 November 2026
Check your site's X-XSS-Protection header
We send one normal request (following redirects) and grade the X-XSS-Protection header on the final response.
Recommended value
X-XSS-Protection: 0
| Value / directive | What it does |
|---|---|
| 0 | Disables the legacy auditor in old browsers that still have one. The recommended value if you send the header at all. |
| 1 | Enables the auditor in "sanitise" mode in old browsers. |
| 1; mode=block | Enables the auditor and blocks the page on detection. Once common advice, now discouraged. |
Why it is deprecated
Internet Explorer, old Edge, Chrome and Safari once shipped "XSS auditors" that tried to spot reflected script in a page and neutralise it. They were bypassable, caused false positives, and could themselves be abused: by triggering the auditor on purpose, an attacker could disable legitimate scripts or leak information about the page (an XS-Leak). Chrome removed its auditor in version 78 (2019), and the other browsers dropped theirs too. Firefox never had one.
What to send instead
The OWASP Secure Headers Project recommends either not sending X-XSS-Protection or sending X-XSS-Protection: 0, and relying on a Content-Security-Policy for XSS protection. Scanners that still flag a missing 1; mode=block are out of date.
How to set X-XSS-Protection
nginx
# inside your server { } block
add_header X-XSS-Protection "0" always;
Apache
# .htaccess or virtual host (needs mod_headers)
Header always set X-XSS-Protection "0"
Laravel middleware
// app/Http/Middleware/SecurityHeaders.php
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-XSS-Protection', '0');
return $response;
}
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->append(\App\Http\Middleware\SecurityHeaders::class);
})
Express (Node.js)
app.use((req, res, next) => {
res.setHeader('X-XSS-Protection', '0');
next();
});
// or: app.use(require('helmet')()) for a sensible default set
Cloudflare
Rules → Transform Rules → Modify Response Header → Create rule.
Match: all incoming requests (or your hostname).
Then: Set static → Header name: X-XSS-Protection → Value: 0
In nginx, an add_header inside a location block discards every add_header inherited from the server block. Repeat your security headers there, or use an include file. The always flag also sends the header on error responses.
Common mistakes
-
Treating
X-XSS-Protection: 1; mode=blockas XSS protection. It protects nothing in current browsers. - Skipping a Content-Security-Policy because this header is "already set".
FAQ
Is X-XSS-Protection still needed?
No. No current browser implements the XSS auditor it controlled. Send 0 or leave it out, and use Content-Security-Policy.
Why not X-XSS-Protection: 1; mode=block?
In the old browsers that honour it, the auditor could be abused to leak information or break pages. OWASP recommends 0.
Related guides
Headers are one of 30+ things attackers check
The free StackShield scan also checks for exposed .env files, debug mode, leaked tooling, weak TLS and more, from the outside, in about a minute.
Run a free scan