Cross-site scripting (XSS) is an injection attack which is carried out on Web applications that accept input, but do not properly separate data and executable code before the input is delivered back to a user’s browser.
There are a number of security controls that can be used in concert to drastically reduce or entirely remove the threat of cross-site scripting. They include:
- Input validation - determines if an end user’s input matches the expected format. For example, a browser-side script would not be expected in a phone number field.
- Content Security Policy (CSP) - restricts which scripts can be run or loaded on a Web page.
- Output encoding - tells the browser that certain characters it is going to receive should be treated as display text, rather than executable code.
A typical web page will contain many contexts including, but not limited to: HTML body, HTML attribute, script and CSS. Each of these output contexts relies on different character encodings to prevent the execution of cross-site scripting payloads. Many web languages and frameworks have template engines available that can automatically set the output context for variable data which will be included in the final Web page.
Blacklist input validation, including Web application firewalls (WAFs), should not be counted on to prevent cross-site scripting attacks. Blacklists are inherently a reactive security measure, dependent upon lists that are often out of date and incomplete. Output encoding and content-security policies are the strongest solution to the problems XSS attacks pose, but do have limitations: output encoding must be properly set for the expected output context and CSP policies need to be configured so that they are as restrictive as possible.