Skip to content

X-XSS-Protection: header should be disabled by default #230

Closed
@ThunderSon

Description

@ThunderSon

Following a decision by Google Chrome developers to disable Auditor, developers should be able to disable the auditor for older browsers and set it to 0.
The X-XSS-PROTECTION header was found to have a multitude of issues, instead of helping the developers protect their application.
The following discussion describes the issue at hand with more references: OWASP/CheatSheetSeries#376
A PR is currently open to tackle the issue at the CheatSheet Series project: OWASP/CheatSheetSeries#378

If approved, we can help with creating a PR for this issue.
Available for further discussions 😄

Activity

thelebdev

thelebdev commented on Apr 9, 2020

@thelebdev

Commenting to follow this issue and possibly offer my help with the potential PR if approved.

EvanHahn

EvanHahn commented on Apr 9, 2020

@EvanHahn
Member

Is there a place I can go to learn more about the security issues caused by X-XSS-Protection? I didn't see anything from the resources you shared.

EvanHahn

EvanHahn commented on Apr 9, 2020

@EvanHahn
Member
thelebdev

thelebdev commented on Apr 10, 2020

@thelebdev

However this, too, was found to be vulnerable to exploits after research detailed how the ‘block’ function could be abused to exfiltrate information through so-called cross-site leak (XS-Leak) exploits.

After some back and forth, XSS Auditor was eventually switched back to filter mode this year because of the difficulty in fixing XS-Leak based attacks.

Researcher terjanq detailed in April how he was able to abuse the filter mode by bypassing the DOM validator for a CTF challenge using the well-known technique of abusing the filter to disable scripts.

He effectively tricked Chrome into believing that non-malicious script was attempting to execute XSS, allowing him to bypass code that implements security measures and execute script that he had inserted, causing XSS.

Source: First link provided by @ThunderSon (https://portswigger.net/daily-swig/google-deprecates-xss-auditor-for-chrome)

ThunderSon

ThunderSon commented on Apr 10, 2020

@ThunderSon
Author

The major attack vector against the block method is the xsleaks attack. Google's services are setting the header to 0 as well (google.com is one example). If you want me to explain it, I certainly can, I'd just prefer to understand what you require from my side on top of the already mentioned information.
A video containing a CTF challenge pertaining to this weakness: https://youtu.be/HcrQy0C-hEA?t=444
It mainly abuses privacy and allows information exfiltration (state, data, etc.)

EvanHahn

EvanHahn commented on Apr 10, 2020

@EvanHahn
Member

Does the video explain the XS-Leak attack? If not, none of the resources I've looked at describe it in detail. It's useful to have the high-level explanation (i.e., "[tricking] Chrome into believing that non-malicious script was attempting to execute XSS"), but I would also like to see a proof of concept.

If it's sensitive, feel free to email me@evanhahn.com or send me a chat message on Keybase (no account needed).

ThunderSon

ThunderSon commented on Apr 11, 2020

@ThunderSon
Author

XS-Leak attacks attempt to circumvent these [SOP, CORS, etc.] security controls by analyzing response times and other factors in order to infer user data.

XS-Search came as a research study after XS-Leak attacks were identified. The video I provided you with is a PoC.

Kindly note I do not have the luxury to run a PoC, I can provide you with this:

EvanHahn

EvanHahn commented on Apr 15, 2020

@EvanHahn
Member

Interesting, I think I understand now.

As for being able to disable this header: I think that's worth doing. I should give the option to set it to 0.

Then there's the question of what the default value should be. I'm not sure how to proceed here, and would love feedback.

A web author seems to have two options with this header:

  1. Disable it. This opens them up to trivial cases of reflected XSS.
  2. Enable it (in either block mode or filter mode). This may protect them against some reflected XSS attacks but opens them up to some side-channel leaks.

Ideally, a developer would protect themselves by disabling the filter and doing XSS protections by themselves. If every developer were well-versed in security, this is fine.

But a big reason people use this mode (and its parent module, Helmet) is because you just have to use it and then you can forget about it, without having to understand too much. Should I try to protect users from trivial reflected XSS but expose them to cross-origin leaks, or should I protect them from cross-origin leaks but expose them to trivial reflected XSS?

My leaning would be to disable the header and make sure to tell people that this header does not protect them against XSS. What do you think?

ThunderSon

ThunderSon commented on Apr 15, 2020

@ThunderSon
Author

Hi @EvanHahn ! Thank you for taking the time to understand the issue at hand 😄
The recommendation as a security community is to have a default value of 0 so that browsers don't set their own defaults.

As an offensive tester, once I detect a reflected XSS, bypassing the auditor becomes really simple. This is a reason to why it's being deprecated. It's not effective in what it does. It will only stop basic attacks (basic attacks are low percentage of the whole attack spectrum). If that's the threat model, there's a bigger issue here.

Your last sentence is truly on point. Advising developers to try applying the CSP header is a much better alternative. It indeed is harder, yet it provides better security.
Setting the XSS header provides a false sense of security, and that is not what we should be promoting in terms of security.

If I can help you in any way, please let me know.

EvanHahn

EvanHahn commented on Apr 15, 2020

@EvanHahn
Member

I'll spend some time thinking about this and will try to figure out a plan. Thanks!

ThunderSon

ThunderSon commented on May 3, 2020

@ThunderSon
Author

@EvanHahn Hi! We will be opening an issue of this in the cheatsheetseries project to properly update the code examples and close the current PR. Please let me know when the update happens. Stay safe! 😄

EvanHahn

EvanHahn commented on May 25, 2020

@EvanHahn
Member

To anyone reading this issue who wants to disable the header: you don't need this module. Here's a very short piece of custom middleware that does the trick:

app.use(function (req, res, next) {
  res.setHeader('X-XSS-Protection', '0');
  next();
});

As I said before, I think users should be able to set the header's value to whatever suits them. If that's 0, great—if that's 1; mode=block, that's okay too.

But what should the default value be?

  1. Setting the default to 1; mode=block protects everyone from trivial XSS but puts everyone at risk of side-channel attacks.
  2. Setting the default to 0 protects everyone from side-channel attacks, but puts some people at risk for trivial XSS.

No matter what we choose, the default will put some people at risk.

I'm coming around to the idea that the default should be 0 but there should also be a strong default Content Security Policy set by Helmet. And again: users should be able to change the default to whatever suits them.

The Secure Headers module is also dealing with this issue and I want to discuss with them a bit, but that's my tentative plan.

changed the title [-]Missing Option to Disable the Header[/-] [+]X-XSS-Protection: header should be disabled by default[/+] on Jul 10, 2020

28 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @EvanHahn@RezaRahmati@ThunderSon@thelebdev

      Issue actions

        X-XSS-Protection: header should be disabled by default · Issue #230 · helmetjs/helmet