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 / directiveWhat 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=block as 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.

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