Web security: XSS

Eighth post in the web security series.

Cross-site scripting (XSS) is the ability an attacker has to execute code (typically javascript) on a vulnerable web application. This is the most common attack against websites. In my previous posts there was some techniques to mitigate XSS vulnerabilities but the best way to prevent them is to not write them.

There are different kind of XSS, but the problem is usually the same: user provided data not being properly sanitized and/or escaped.

Each time you display user provided data in a web page you must escape it. Escaping HTML content is basically replacing all HTML characters in the content by their HTML entity counterpart. For example the character < used for opening an HTML tag is replaced by &lt;.

In the end you will see the user content provided data instead of having it being interpreted as HTML code.

Depending on the language/frameworks you are using this can be more or less easy. You should definitely use a framework that makes it the default.

For instance in Java when using the framework Thymeleaf, HTML is generated by templates that make you use the th:text command to display content. th:text escape HTML code by default.

In raw PHP you should use something like the function htmlspecialchars on the data you want to display instead of outputing the variable as is.

In Drupal, usually data you are going to display are also localized so the function t is used, to which you given a string containing variables that are replaced by values given in arguments. Those variables can be inserted in 3 differents ways:

  • !variable
  • @variable
  • %variable

As you can see it's not at all self explanatory and they all have a very different behavior. !variable is replaced as is, data are not escaped, you must not use it to display user provided content unless you already escaped it manually with something like the function check_plain (bad naming again), @variable escape the content, so that's what you should use, %variable escape the content and put it inside an em tag…

In Symfony framework, the Twig templating system is used istead of PHP templates, displaying content is done that way: {{ "{{ variable "}}}}, and is escaped by default.

Prefer using a templating system like Thymeleaf or Twig, they require you to write more code to have a less secure application, so developers (they are all lazy ;-)) will tend to write more secure code by default.

If you are processing HTML using javascript on the client side, there is the same issue, you must sanitize/escape the data you are handling.

Note:

Comments Add one by sending me an email.