Last week we finished up input validation, which represents one half of the solution towards preventing XSS. This week we will cover the other half; output encoding. Output encoding protects the application in the event that malicious script data somehow makes its way into the database or a form parameter. It is a fail safe if you will.
ASVS 6.1 Requirement:
ASVS 6.1 Solution:
Escaping or encoding data prior to output to the browser will help to ensure that malicious code is not executed, and is instead rendered as text. PHP provides two functions for encoding HTML data; htmlentities and htmlspecialchars. We will use htmlentities, as it encodes all characters for which there are HTML character entity equivalents (thorough). The htmlspecialchars function operates as its name suggests; only certain designated special/dangerous characters are encoded (&, ‘, “, <, >).
$data = htmlentities($_POST['value'], ENT_QUOTES, "UTF-8", false); print("$data");
It is just as simple as that. Here we are assigning the POSTed form value of ‘value’ to the $data variable in an encoded form and later printing/outputting it to the browser. The first value passed to htmlentities is the data to be encoded. The following constant tells htmlentities what to do with quotes; ENT_QUOTES provides the most secure mechanism, which is to encode single AND double quote characters. The third variable passed to htmlentities sets the character set to be used. The final variable tells htmlentities whether or not to double encode (encode an already encoded value). Double encoding is unnecessary and could modify how the data is displayed.
This same function should be used to encode user supplied data that is being pulled from a database, xml file, etc. All user supplied data should be output encoded regardless of its origin.
ASVS 6.2 Requirement:
Verify that all output encoding/escaping controls are implemented on the server side.
ASVS 6.2 Solution:
This is an easy one, don’t escape/encode data on the client side as this can be bypassed. Use the htmlentities function within your server side PHP code to output encode user supplied data.
ASVS 6.3 Requirement:
Verify that output encoding /escaping controls encode all characters not known to be safe for the intended interpreter.
ASVS 6.3 Solution:
This was covered above in our solution for 6.1. Use htmlentities instead of htmlspecialchars, and you will be certain to encode everything with an HTML entity equivalent.
Note: We are skipping ASVS 6.4 through 6.8 as they cover escaping for SQL, XML, LDAP and other types of injection that will be reviewed in later blog posts.
ASVS 6.9 Requirement:
Verify that for each type of output encoding/escaping performed by the application, there is a single security control for that type of output for the intended destination.
ASVS 6.9 Solution:
Do not vary your security controls depending upon the destination (SQL database, LDAP, XML, etc). Perform the same type of output encoding for all user supplied data sources and regardless of the destination of the data. This will prevent malicious script code from later being displayed in some way, possibly by a different application.
ASVS 6.10 Requirement:
Verify that all code implementing or using output validation controls is not affected by any malicious code.
ASVS 6.10 Solution:
Scan your code for viruses, or any malicious backdoors. Perform manual and automated code reviews.
And that is it for output encoding. This is a very simple control to implement that will go a long way towards protecting your web applications from XSS attacks.
We have completed the sections in the OWASP ASVS covering controls to prevent XSS attacks. However, the next post will provide an input validation follow up that provides a couple additional security layers to help protect your applications. After that post, we will move on to a new OWASP 2010 Top 10 section.
As always, please provide any feedback you have, positive or negative.