1

I am a newbie in web application development. My application is using AngularJS\NodeJS. A security tool reported reflected XSS vulnerability in our application. From my search on the internet I found that there is a HTTP X-XSS-Protection response header which appears to protect the application against reflected XSS attacks. However, I am not sure if that should be sufficient for handling the reflected XSS attacks or additionally any input sanitization should also be done in the application.

Gabor Lengyel
  • 14,129
  • 4
  • 32
  • 59
Amit Rastogi
  • 926
  • 2
  • 12
  • 22
  • there is a [small note about that in docs](https://docs.angularjs.org/guide/security#angularjs-templates-and-expressions) – Aleksey Solovey Apr 23 '18 at 10:00
  • tl;dr: angularjs apps should not be mixed with server-side templates. You get the data via API calls _after_ the static HTML was loaded/rendered – Aleksey Solovey Apr 23 '18 at 10:21

2 Answers2

2

X-XSS-Protection is not enough, and is already enabled by default in most browsers. All it does is it enables the built-in XSS protection in browsers, but the trick is, to the best of my knowledge (maybe somebody will correct me) it is not specified what exactly the browser should do. Based on my experience, browsers only filter the most trivial XSS, when there is a parameter with javascript between script tags - such javascript from the parameter will not be run. For example if the parameter is

something <script>alert(1)</script> something

this will not be run by the browser. And apparently that's it.

For example if you have server-side code like

<div class="userclass-{{$userinput}}">

then this can be exploited with the string abc" onclick="alert(1)" x=", and this will go through the built-in filter in any browser I tried.

And then we haven't talked about stored or DOM XSS, where this protection is totally useless.

With Angular, it is slightly harder to make your code vulnerable to XSS (see here how to bind stuff as html for example), but it is by far not impossible, and because you would almost never need an actual script tag for that, this built-in protection has very limited use in an Angular app.

Also while input validation/sanitization is nice to have, what you actually need against XSS in general is output encoding. With Angular, that is somewhat easier than with many other frameworks, but Angular is not the silver bullet, your application can still be vulnerable.

In short, anytime you display user input anywhere (more precisely, anytime you insert user input into the page DOM), you have to make sure that javascript from the user can't be run. This can be achieved via output encoding, and secure Javascript use, which can mean a lot of things, mostly using your template engine or data binding in a way that only binds stuff as text, and not anything else (eg. tags).

Gabor Lengyel
  • 14,129
  • 4
  • 32
  • 59
2

What X-XSS-Protection does is browser dependent and can't be relied upon for security. It is meant as an extra layer to make it more difficult to exploit vulnerable applications, but is not meant as a replacement for correct encoding. It is a warning that an application is vulnerable and the responsibility to fix it is on the application developers.

This is why in Chrome, errors in the XSS filter are not even considered security bugs. See the Chrome Security FAQ:

Are XSS filter bypasses considered security bugs?

No. Chromium contains a reflected XSS filter (called XSSAuditor) that is a best-effort second line of defense against reflected XSS flaws found in web sites. We do not treat these bypasses as security bugs in Chromium because the underlying issue is in the web site itself. We treat them as functional bugs, and we do appreciate such reports.

The XSSAuditor is not able to defend against persistent XSS or DOM-based XSS. There will also be a number of infrequently occurring reflected XSS corner cases, however, that it will never be able to cover. Among these are:

  • Multiple unsanitized variables injected into the page.
  • Unexpected server side transformation or decoding of the payload.

And there are plently of bugs. There are ways found to bypass the filter regularly. Just last week there was a fairly simple looking injected style attribute bypass.

Such a filter would need to tell where values in the output have come from by only looking at the input and the output, without seeing any templates or server-side code. When any processing is done to the input, or there's multiple kinds of decoding occurring, or multiple values are combined together, this can be very difficult.

Much easier would be to take care of the encoding at the template level. Here, we can easily tell the difference between variable values and static code because they haven't been merged together yet.

fgb
  • 18,439
  • 2
  • 38
  • 52