4

Assuming that users are using modern browsers, is implementing a strict CSP policy enough to prevent all XSS attacks?

I'm working on a Backbone app, and am wondering if I still need to be escape user data on the client to display all the time.

Michal Koczwara
  • 1,580
  • 3
  • 15
  • 27
Akshay Rawat
  • 247
  • 4
  • 7
  • Yes, when properly implemented and available it can mitigate XSS. None of these answers (3 March 2017) directly answers the question but instead talk around the problem of security and include info about how this can be the case. (Came here trying to make this general determination as well as part of due diligence.) However note that I haven't yet written tests or an audit that provides evidence (and neither do any of these answers or online material that I've found so-far). – jimmont Mar 03 '17 at 19:45

3 Answers3

1

Content Security Policy (CSP) is just a one layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. However please bear in mind that security is all about defense in depth so yes you still should implement additional security layers and please remember that preventing Cross-site Scripting Attacks(XSS) vulnerabilities in all languages requires two main considerations:

  • the type of sanitization performed on input
  • location in which that input is inserted.

It is important to remember that no matter how well input is filtered; there is no single sanitization method that can prevent all Cross-site Scripting (XSS).

The filtering required is highly dependent on the context in which the data is inserted. Preventing XSS with data inserted between HTML elements is very straightforward. On the other hand, preventing XSS with data inserted directly into JavaScript code is considerably more difficult and sometimes impossible.

For the majority of PHP applications, htmlspecialchars() will be your best friend. htmlspecialchars() supplied with no arguments will convert special characters to HTML entities.

Another function exists which is almost identical to htmlspecialchars(). htmlenities() performs the same functional sanitization on dangerous characters, however, encodes all character entities when one is available.

strip_tags() should not be used exclusively for sanitizing data. strip_tags() removes content between HTML tags and cannot prevent XSS instances that exist within HTML entity attributes. strip_tags() also does not filter or encode non-paired closing angle brackets. An attacker may be able to combine this with other weaknesses to inject fully functional JavaScript on the page.

addslashes() is often used to escape input when inserted into JavaScript variables.

Michal Koczwara
  • 1,580
  • 3
  • 15
  • 27
1

Assuming that users are using modern browsers, is implementing a strict CSP policy enough to prevent all XSS attacks?

Not all modern browsers implement CSP (IE has only very limited support). But assuming that the browser has proper CSP support and that you CSP is very strict (no unsafe-eval!) then it can be used to successfully prevent XSS. But...

I'm working on a Backbone app, and am wondering if I still need to be escape user data on the client to display all the time.

There are other attacks apart from XSS. If you don't escape properly then HTML injection can still be used to affect the parts of the page which are not covered by CSP, like:

  • Include links (<a href=...) which point to attacker-controlled resources. Depending on the page also existing links might be changed.
  • Include new forms or change the submission target for existing forms. This way you could grab sensitive data.
  • Redirect the user to drive-by-downloads by including HTML using meta refresh.
  • an possible more
Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • The [`form-action`](https://w3c.github.io/webappsec/specs/content-security-policy/#directive-form-action) directive can protect against form targets being included or changed. – SilverlightFox May 22 '15 at 09:04
  • Can you explain how CSP no unsafe-eval prevents XSS? Or maybe how XSS happens? If a MITM can change my content why can't he change my headers and remove the CSP headers? – gman Aug 31 '15 at 07:34
  • @gman: XSS is unrelated to MITM and one does not assume MITM for this attack. Explaining what XSS is would be out of scope for this question. To learn about XSS see [OWASP](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)) or [Wikipedia](https://en.wikipedia.org/wiki/Cross-site_scripting). – Steffen Ullrich Aug 31 '15 at 08:45
0

No - this is partly due to browser support. For example, Internet Explorer only partially supports Content Security Policies.

Also, a CSP should be seen as an effective secondary solution for XSS. Think of it as protecting against code where the developer has forgotten to output encode correctly. This will protect your application in supported browsers while the fix is created and before it is deployed to your production systems.

Correctly encoding output ensures that web standards are followed, which increases both security and functionality. For example, you would not want your web application to display incorrectly if the user has decided to put <> characters in their input.

Additionally, it may be possible for nefarious users to break your site in other ways, despite the CSP. For example, including other scripts from allowed sources, or including your scripts twice to create a Denial of Service for others users where the output is displayed (as the duplicate breaks the page logic). An attacker would also be able to edit your site content in other ways.

In summary I would advise against using additional security features in order to cut corners elsewhere. They should be complimentary - always think defence in depth.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • Double inclusion of an allowed script to do Denial of Service is only relevant for Stored XSS though. (not reflective/dom-based XSS). But this is a good example of something CSP can't protect against! – Tobias Bergkvist Feb 25 '21 at 16:27