Resolving the security ‘Missing X-XSS-Protection’ header issue

Today in this article, we shall see how to resolve security vulnerabilities like ‘Missing X-XSS-Protection‘.

Updated November 2026: current guidance to send 0 or omit the header, a CSP replacement, server config with verification, and an FAQ.

Today we will cover the below aspects,

The HTTP X-XSS-Protection is a header and type of response header. It is a feature of most common browsers including Internet Explorer, Chrome, and Safari which controlled the browser’s built-in reflected cross-site scripting (XSS) filter. The header is now deprecated and non-standard, and the filter has been removed from major browsers.

Why use a response header – X-XSS-Protection

If a malicious input is being injected into the browser, this header lets your browser define action. If a cross-site scripting attack is detected, the browser will sanitize the page and the malicious part will either be removed OR the browser will prevent rendering of the page and will block an attack (mode=block).

Syntax

Below are the four options for enabling Cross-site scripting.

X-XSS-Protection: 0 
X-XSS-Protection: 1 
X-XSS-Protection: 1; mode=block 
X-XSS-Protection: 1; report=<report-uri>

X-XSS-Protection: 0

Disables XSS filtering.

X-XSS-Protection: 1

  • Enables Cross-site scripting (XSS) filtering.
  • Older browsers used this as the default when the header was absent, but this filtering is now deprecated and can itself introduce XSS vulnerabilities, so don’t rely on it.
  • If a cross-site scripting attack is detected, the browser will sanitize the page and the malicious/unsafe part will be removed.

X-XSS-Protection: 1; mode=block

  • Enables Cross-site scripting (XSS) filtering.
  • Historically this blocked the page when an attack was detected. It gives no benefit in modern browsers, and OWASP now recommends omitting the header or sending 0 instead.
  • The browser prevents the rendering of the page.

X-XSS-Protection: 1; report=<report-Uri>

  • Enables Cross-site scripting (XSS) filtering.
  • If a cross-site scripting attack is detected, the browser will sanitize the page and report the violation.
  • The report will be sent to <report-URI>

For ASP.NET Core below is the code of how I have added the X-XSS-Protection” header using the middleware component,

app.Use(async (context, next) =>
            {
                context.Response.Headers.Add("Content-Security-Policy", "default-src 'self';");

                context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
                context.Response.Headers.Add("X-XSS-Protection", "1");
                context.Response.Headers.Add("Strict-Transport-Security", "max-age=31536000 ; includeSubDomains");

                await next.Invoke();
            });

Use a similar technique in any language or framework, but send X-XSS-Protection: 0 (or omit the header) rather than 1; mode=block, and add a Content-Security-Policy.

Once enabled, you shall see the response with XSS header,

Missing X-XSS-Protection

References :

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published (2026) best practices and guidelines for software design and development.



Should you add the X-XSS-Protection header or send 0?

Don’t add X-XSS-Protection: 1; mode=block. Send X-XSS-Protection: 0 or leave the header out, and rely on Content-Security-Policy (CSP) as the real control. That means the "1" value in the ASP.NET Core middleware above should become "0".

Why is the header no longer recommended?

MDN marks the header as non-standard and deprecated. The browser feature behind it, the XSS auditor, has been removed from major browsers, so the header does nothing there.

Note: The XSS auditor was a smoke detector that guessed at fires by pattern-matching the request against the page. Detectors like that give false alarms and can be fooled, and this one could also be turned against the pages it was guarding.

In older browsers the filter could introduce XSS holes on otherwise safe pages and leak cross-origin data. MDN and the Helmet maintainers both point this out. That is why OWASP says to omit the header or explicitly send 0.

What did it never protect against?

It only targeted reflected XSS, where request data is echoed back into the response. Stored and DOM-based XSS were never covered. The real fix is output encoding for the context where data lands (HTML, attribute, JavaScript, URL), backed by a CSP that blocks inline scripts.

Why do scanners still report it?

Many scanners still check for the header by name. A “missing header” finding on a modern stack is usually a false positive. Scanners can also flag the old 1; mode=block value, and Spring Security’s default sends exactly that.

How should you respond to a pen-test finding?

  1. Send 0: this satisfies most scanners and switches off the old filter in any legacy browser.
  2. Or omit it and document the exception: cite your CSP, the MDN deprecation notice and the OWASP HTTP Headers Cheat Sheet.
  3. Ship a real CSP: start with default-src 'self', a nonce-based script-src and object-src 'none', then test it against your app.
  4. Verify after deploy: the header should be absent or exactly 0, and not duplicated by both your app and a proxy.

Which value should you use?

This table compares the four values and what to do with each.

ValueWhat it didRecommendation
0Turns the filter offUse it, or omit the header
1Filter on, strips suspicious partsAvoid; sanitizing could open new holes
1; mode=blockFilter on, blocks the pageAvoid; no benefit in modern browsers, and scanners flag it
1; report=<uri>Filter on, sends violation reportsDon’t use; it was Chrome-only and is gone with the auditor

For violation reporting, use the CSP report-to directive instead.

Frequently asked questions

Is a missing X-XSS-Protection header a real vulnerability?

Usually no. The header is deprecated and non-standard, and the browser filter it controlled has been removed from major browsers, so a scanner finding for its absence is typically a false positive. Rely on a strong Content-Security-Policy and proper output encoding instead. If your security team needs a paper trail, document the exception in the report and note which controls cover XSS.

Should I set X-XSS-Protection to 0 or to 1; mode=block?

Use 0 or omit the header. MDN and the OWASP HTTP Headers Cheat Sheet both advise against enabling the filter, because it could introduce XSS holes or leak data in otherwise safe sites. The value 1; mode=block gives no benefit in modern browsers, and some scanners now flag it as a finding. That means the "1" value in the middleware example above is worth changing to "0".

What replaces X-XSS-Protection?

Content-Security-Policy (CSP). A policy that disallows inline JavaScript makes the old protection largely unnecessary. A reasonable starting shape is default-src 'self', a nonce-based script-src and object-src 'none'. Test it against your own pages before enforcing it, since inline scripts and third-party resources will break if the policy doesn’t allow them.

Does X-XSS-Protection stop stored or DOM-based XSS?

No. It only ever targeted reflected XSS, where request data is echoed straight back into the page. Stored and DOM-based XSS need output encoding, careful input handling and a strong CSP. Adding the header was never a fix for those.

Leave a Reply

Your email address will not be published. Required fields are marked *