Web Application Security Guide/Cross-site scripting (XSS)

Cross-site scripting (XSS)

XSS vulnerabilities occur if user input included in the output of a web application is not escaped correctly. This type of vulnerability allows attackers to inject content into the web application output. This can be used to inject a false login form (reporting the input to an attacker) or malicious JavaScript code which can steal cookies and information or execute actions using the user’s permissions. XSS vulnerabilities are separated into two main categories, reflected (non-persistent) and persistent vulnerabilities.

Reflected XSS vulnerabilities include the user input only in the output directly following the request. Thus, the attacker needs the user to follow a malicious link or make a malicious POST request. The former can be done by including the link as an IFRAME; the latter can be done using JavaScript. Both vulnerabilities do require that the user visits a malicious/compromised site, but they do not necessarily require user interaction.

Persistent XSS vulnerabilities store the user input and include it later outputs (e.g. a posting in a forum). This means that the users do not need to visit a malicious/compromised site.

To prevent this type of attack

  • Escape anything that is not a constant before including it in a response as close to the output as possible (i.e. right in the line containing the “echo” or “print” call)
  • If not possible (e.g. when building a larger HTML block), escape when building and indicate the fact that the variable content is pre-escaped and the expected context in the name
  • Consider the context when escaping: Escaping text inside HTML is different from escaping HTML attribute values, and very different from escaping values inside CSS or JavaScript, or inside HTTP headers.
  • Explicitly set the correct character set at the beginning of the document (i.e. as early as possible) and/or in the header.
  • Ensure that URLs provided by the user start with an allowed scheme (whitelisting) to avoid dangerous schemes (e.g. javascript:-URLs )
  • don’t forget URLs in redirector scripts
↑Jump back a section

Rationale

Escaping data directly at the output location makes it easier to check that all outputs are escaped – each and every variable used as a parameter for an output method must either be marked as pre-escaped or be wrapped in a corresponding escape command.

Different contexts require completely different escaping rules. A “)” character with no dangerous meaning in HTML and HTML attributes can signify the end of an URL path in CSS.

Not setting the character set may lead to guessing by the browser. Such guessing can be exploited to pass a string that seems harmless in your intended encoding, but is interpreted as a script tag in the encoding assumed by the browser. For HTML5, use <meta charset="utf-8" /> as the first element in the head section.

URLs can be dangerous, too. User-provided links should be checked against a scheme whitelist, as the javascript scheme is not the only dangerous one. Other schemes can trigger possibly unwanted action. If only web links are to be allowed, require the URLs to start with “http://” or “https://”.

↑Jump back a section
Last modified on 18 April 2013, at 03:47