Show TOC

 Avoiding XSS by Using Correct Output EncodingLocate this document in the navigation structure

As described in Output Encoding Contexts, XSS occurs whenever a Web application uses an attacker-controlled value for composing the application's HTML interface. To avoid this problem, all untrusted values have to be properly sanitized before they are used for creating the HTML or JavaScript. This sanitation step has to enforce that the untrusted values are interpreted by the Web browser purely as data and in no circumstances as mark-up or JavaScript code.

To ensure this, a processing step called output encoding has to be applied to all untrusted values before it leaves the application and the proper encoding context could be identified. Output encoding transforms all characters of the untrusted value, which might cause the Web browser's rendering process to interpret the data as syntax, into an alternative representation. In its rendered form, this alternative representation should still represent its original value.

Note

Occasionally the terms "escaping" or "output escaping" are used to describe the process for output encoding. For the remainder of this document, treat the terms "encoding" and "escaping" as synonyms.

Tip

For example, the less than sign (<) is used in HTML to signify the start of an HTML tag. To enforce the Web browser's rendering process to interpret this character correctly, the application has to transform all less than sign (<) characters in the potentially attacker-provided data into the corresponding HTML less than sign (<) character entity to be displayed as such, and not as HTML markup.

The output encoding method to use is highly dependent on the current context within the generated HTML in which the values are injected. (For more information, see the sections that follow.)

The Relationship of Output Encoding to Input Validation

The concepts of input validation and output encoding are often used in the same context and frequently confused. However, they both have distinct purposes and properties.

Input validation is the process of ensuring that received data satisfies the expectations of the application in respect to factors such as size, character set, or syntactical structure. If the set of expected values for a given parameter is clearly defined, it is feasible to enforce the corresponding characteristics. For example, the data format of a time or date value can be expressed reliably with regular expressions and therefore, the application can test the validity of the received data before processing it.

However, input validation is not suitable to ensure bullet-proof protection against XSS for the following reasons:

  • The expected syntactical structure of received data might be underspecified or even partially unknown, rendering complete input validation infeasible.
  • Due to the functional properties of the application, it might be necessary to allow input which in certain output contexts could cause XSS issues. In such cases, the input cannot be rejected, and therefore, input validation cannot provide protection.
  • Frequently, it is unknown in which contexts received data will end up being used during processing. However, for XSS protection it is highly relevant in which syntactical context the data is used in the output HTML, JavaScript, or CSS (see below), as the syntactical properties of potential harmful data differs significantly depending on the applicable context. For this reason, a general detection or rejection of potential dangerous code is unreliable.

Therefore, input validation can always be regarded only as a first line of defense when it comes to defending against XSS. It is vital to the application's security that output encoding is applied in all cases, no matter how thoroughly the input was validated beforehand.

Nonetheless, input validation is an essentially task that has to be done to ensure functional properties as well as defending against other classes of security issues (such as parameter tampering, forced browsing, or path traversal).

Note

Avoid applying preemptive input encoding, for example, by using <cl_http_request>->get_form_fields( formfield_encoding = 2 ). As mentioned above, it might not be known how the data is processed when it received. As a consequence, input encoding might fail to provide the desired security, and instead cause functional problems.

Contexts and Mixed Contexts

Web pages are made up of entities like HTML elements, attributes on an element, scripts and CSS stylesheets. Depending on the type of entity, a different encoding is required. Each of these types is referred as context in this documentation.

Mixed contexts are contexts where multiple contexts are being used, for example, using a script in an attribute tag of an HTML element.

Which Characters to Encode or Escape

Escaping is a technique used to ensure that characters are treated as data, not as characters that are relevant to the interpreter's parser. The type of the escaping depends on the context in which characters are used. For example, in the JavaScript context, the result of escaping the carriage return (CR) and line feed (LF) control sequences are backslash r (\r) and backslash n (\n),respectively.

The terms escaping and encoding often mean the same, especially in the context of HTML. In the JavaScript context, encoding means that control sequences like CR and LF are encoded into \x0d and \x0a, respectively. In this guide we always encode characters to ensure that in a mixed context the different parsers do not allow for breaking out of its context.

Tip

For example, in the JavaScript context, you can escape the double quotation mark (") to backslash followed by the double quotation mark (\").

For HTML, if you allow for input data in HTML element event handlers, this is a problem because the HTML parser does not consider the backslash (\) as an escape character, and therefore a non-HTML-escaped backslash followed by the double quotation mark (\") would actually end the attribute.

For more information, see http://www.w3.org/TR/html40/interact/scripts.html#h-18.2.3.

Context-Specific Character Encoding

Although encoding can prevent the execution of untrusted values, there are contexts that cannot be protected with character encoding. You should avoid using such untrusted contexts. If this is not possible, then you must validate them with whitelist filtering.

The different contexts in which different encoding rules are needed are explained more in detail in Output Encoding Contexts. Examples are also included.

Content-Type-Specific Character Encoding

The character encoding depends on the Content-Type in which a Web framework runs. The optional value charset is the most important setting here. The different character sets have some overlaps, in particular between character 127 (0x7f) and 255 (0xff).

If your application is running on an AS ABAP (Unicode) or AS Java, then encoding of the necessary character ranges is done properly.

Otherwise, take the following into consideration:

  • You should use a transformation of your content into a general character set, whereby, we recommend using the UTF-8 character set. If you ensure that this character set is used, and you ensure that the option charset=UTF-8 in the Content-Type response header, then you do not have to encode all characters above 255 (0xff).
  • If the Web framework cannot ensure the setting of the HTTP response header Content-Type: with the value option charset=UTF-8 and the correct transformation of the data into UTF-8, then you should always encode characters above (>) 255 (0xff) according the rules described in the section Context-Specific Character Encoding. For more information, see the W3C recommendation at http://www.w3.org/International/O-HTTP-charset.
    Note

    If in doubt, encode all characters above 0xff.