Cross Site Scripting (XSS) attacks are amongst the most common types of attacks against web applications. XSS vulnerabilities all fall under the same category, however, a more detailed look at the techniques employed during XSS attacks reveals a multitude of tactics that exploit a variety of attack vectors. This article describes the two most common and useful XSS prevention mechanisms – filtering and escaping.
Filtering for XSS
All XSS attacks affect your web site through some form of client-side user input. Malicious code could come from a simple
<form> submitted by your users or could take a more complex route such as a JSON script, XML web service, or even an exploited cookie. In all cases, the web developer should be aware that the data is coming from an external source and therefore must not be trusted since it may introduce a security vulnerability.
The simplest and arguably the easiest form of cross-site scripting vulnerability elimination would be to pass all external data through a filter. Such a filter would remove dangerous keywords, for example, the infamous
Many web developers choose to implement their own XSS filter mechanisms. They usually write server-side code (in PHP, ASP, or some other web-enabled development language) to search for keywords and replace them with empty strings. A lot of code uses regular expressions for filtering and replacing.
This technique is not a bad one in itself, however, the hackers usually have more experience than web developers and often manage to circumvent simple filters by using techniques such as hex encoding, Unicode character variations, line breaks, and null characters in strings. These techniques must all be catered for and that is why it is recommended to use some sort of library that has been tried and tested by the community at large.
Many libraries exist to choose from and your choice will primarily depend on the back-end technology that your web server uses. What is important is that you choose a library that is regularly maintained by a reliable source. XSS techniques keep changing and new ones emerge all the time so your filters will need to be updated periodically to keep abreast with the changing attacks. If you are using Java, then a good place to go to is the OWASP Java Encoder Project. For PHP, there is a comprehensive library called HTML Purifier, which boasts strict standards compliance and better features than other filters.
The side effect of filtering techniques is that legitimate text is often removed because it matches forbidden keywords. For example, this article would be incomplete if the Acunetix web server simply filtered out all HTML markup. It would be impossible to include text like
alert('you have been hacked'). If you want to preserve the original data (and its formatting) as best as possible you need to relax your filters and employ HTML, Script, and CSS escaping techniques.
Escaping from XSS
Escaping is the primary means to avoid cross-site scripting attacks. When escaping, you are effectively telling the web browser that the data you are sending should be treated as data and should not be interpreted in any other way. If an attacker manages to put a malicious script on your page, the victim will not be affected because the browser will not execute the script if it is properly escaped. In HTML, you can escape dangerous characters by using HTML entities, for example, the
&# sequence followed by its character code.
The two most popular escaping libraries available are the ESAPI provided by OWASP and AntiXSS provided for Microsoft. ESAPI can plug into various technologies such as Java, .NET, PHP, Classic ASP, Cold Fusion, Python, and Haskell. AntiXSS exclusively protects Microsoft technologies and is, therefore, better suited in an all-Microsoft environment. Both libraries are constantly updated to keep up with the latest hacker techniques and are maintained by industry experts who understand changing tactics and emerging technologies.
When to Escape
You cannot just simply escape everything or else your own scripts and HTML markup will not work, rendering your page useless. There are several places on your web page which you need to ensure are properly escaped. You can use your own escaping functions (not recommended) or existing libraries.
Use HTML escaping when untrusted data is inserted between HTML opening and closing tags. These are standards tags such as
<table>, etc. For example:
<div>If this data is untrusted, it must be HTML-escaped.</div>
style and all event handlers such as
onload. For example:
Use CSS escaping when untrusted data is inserted inside your CSS styles. Many CSS styles can be used to smuggle a script into your page. For example:
<div style="background-image: If this data is untrusted, it must be CSS-escaped.">
XSS Attacks Are a Moving Target
Recommendations in this article are by no means exhaustive, however, they should be a good starting point to secure applications. Technology is changing and hacker attacks are getting more sophisticated but by understanding the basics, you can be prepared to prevent future attack techniques that will most definitely arise.
The first step in defending against all XSS attack vectors is to code your web applications carefully and use proper escaping mechanisms in the right places. After that, comprehensive code review and testing should be performed, ideally using an automated XSS scanner such as Acunetix. When updates are made to your web applications, you should scan the affected pages again to ensure that no new vulnerabilities have been exposed.