Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
ThunderSon opened this issue Apr 9, 2020 · 17 comments
Closed

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

ThunderSon opened this issue Apr 9, 2020 · 17 comments
Assignees
Milestone

Comments

@ThunderSon
Copy link

@ThunderSon ThunderSon commented Apr 9, 2020

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 😄

@thelebdev
Copy link

@thelebdev thelebdev commented Apr 9, 2020

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

@EvanHahn
Copy link
Member

@EvanHahn EvanHahn commented Apr 9, 2020

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
Copy link
Member

@EvanHahn EvanHahn commented Apr 9, 2020

@thelebdev
Copy link

@thelebdev thelebdev commented Apr 10, 2020

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
Copy link
Author

@ThunderSon ThunderSon commented Apr 10, 2020

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
Copy link
Member

@EvanHahn EvanHahn commented Apr 10, 2020

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
Copy link
Author

@ThunderSon ThunderSon commented Apr 11, 2020

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
Copy link
Member

@EvanHahn EvanHahn commented Apr 15, 2020

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
Copy link
Author

@ThunderSon ThunderSon commented Apr 15, 2020

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
Copy link
Member

@EvanHahn EvanHahn commented Apr 15, 2020

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

@ThunderSon
Copy link
Author

@ThunderSon ThunderSon commented May 3, 2020

@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
Copy link
Member

@EvanHahn EvanHahn commented May 25, 2020

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.

@EvanHahn EvanHahn transferred this issue from helmetjs/x-xss-protection Jul 10, 2020
@EvanHahn EvanHahn changed the title Missing Option to Disable the Header X-XSS-Protection: header should be disabled by default Jul 10, 2020
@EvanHahn EvanHahn mentioned this issue Jul 10, 2020
36 tasks
@EvanHahn EvanHahn self-assigned this Jul 10, 2020
@EvanHahn
Copy link
Member

@EvanHahn EvanHahn commented Jul 29, 2020

This has been added to Helmet v4, which I plan to release this Sunday, 2020-08-02.

You can install the release candidate with npm install helmet@next if you want to try it out.

@EvanHahn EvanHahn added this to the 4.0.0 milestone Jul 29, 2020
@EvanHahn
Copy link
Member

@EvanHahn EvanHahn commented Aug 2, 2020

Helmet v4 (and x-xss-protection@2) was just released, which disables this header.

Thanks for reporting and for discussing this with me.

@RezaRahmati
Copy link

@RezaRahmati RezaRahmati commented Jun 30, 2021

@EvanHahn Hi Evan, I am using helmet: 4.4.1, still getting x-xss-protection: 0 on response, based on your comment seems it should be 1 by default, right?

Or how can I change the behavior, there is no option in helmet.xssFilter to change the options

@EvanHahn
Copy link
Member

@EvanHahn EvanHahn commented Jun 30, 2021

@RezaRahmati It should be set to 0 in Helmet v4, so what you're seeing is expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants