CVSS3 Score: 6.1 (CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)
OWASP TOP10: A7 - Cross-Site Scripting
SANS/CWE: CWE-79: Improper Neutralization of Input During Web Page Generation
Depending on the type of XSS and the nature of the vulnerable application, the impact of this vulnerability can range from temporarily modifying the contents of the website (during the victim's visit) to total control of the victim's session or even of the browser. Given its prevalence and ease of exploitation, it's often considered a serious risk for any application that contains an area that requires authentication.
This type of vulnerability is quite widespread on the Internet and happens when the application takes user input and prints (outputs) it without properly encode or validate that input. The name reflected comes from the malicious code that is sent to the server and reflected back to the victim's browser, in the source code of the page.
How to Fix
The correct prevention method is to escape the user input data before including it in the response, however, there are some rules you must follow to ensure proper escaping is applied.
If you are using a template system to define the look and layout of your application, it is likely that it has support for auto-escaping data, without much hassle. Depending on the system, you either enable it globally when loading the template system or you have to enable it everything time you echo some code or variable on the page.
Using a template system to generate your pages will probably save you some time and it easier to ensure that is XSS-free, since most of them auto-escape by design, such as the template system used in the Python framework Django.
If you have to do it by hand you must be aware that there isn't a one-size-fits-all solution: the way you escape the input depends on the context of the page where it is being placed. There are four contexts where it is common to place user input. These are:
- HTML body and HTML element attributes
- CSS and style attributes
HTML BODY AND ELEMENT ATTRIBUTES CONTEXT
This rule applies to data inserted into HTML body elements, such as div, p, b, td, etc. and also to simple attribute values like width, name, value, id, etc. It must not be used in attributes like href, src, style, or any event handler like onmouseover.
You should use htmlspecialchars in PHP, like this:
echo htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
In this case you should escape any input by converting it to its unicode representation. For instance, ; should become \u003b. If you don't have access to a function that does this conversion, you have the option to convert to the \xHH format, where HH its the character hex representation.
CSS AND STYLE TAG CONTEXT
To escape user data within CSS or within a style tag you should use the \HHHHHH format, where HHHHHH is hex representation of the character, padded with the necessary zeros.
URL GET PARAMETERS CONTEXT
This context is for URL based attributes, such as href and src. Input within these should be passed through an URL encoding function. All languages have functions to perform such conversion, for instance, in Python you would use urllib.urlencode.