XSS filter evasion
What is XSS filter evasion?
XSS filter evasion is a collective term for various techniques used by attackers to bypass filters implemented to protect web applications against cross-site scripting (XSS).
What are XSS filters?
XSS filters are one of the primary methods used to prevent all types of XSS vulnerabilities: stored XSS, reflected XSS, and DOM-based XSS. They work by finding patterns that are typical of XSS attack vectors and removing such suspicious code from user input data. Patterns are typically defined using regular expressions. Such pattern-based matching is very difficult for two main reasons:
- Patterns that are typical of XSS payloads may also be used legitimately in web page content, as with the examples presented in this article. An effective filter needs to allow for this to avoid false positives.
Examples of XSS filter bypass methods
The following are the most common methods used by attackers in their malicious code to fool XSS filters. Of course, all these methods may be combined or refined. You can find more examples in the OWASP XSS Filter Evasion Cheat Sheet, based on the XSS Cheat Sheet by RSnake.
Using various character encodings
The simplest XSS technique used to defeat filters is to encode characters that may trigger a filter. Many different encodings can be used, for example, base64, HTML entities, or others. Available encoding techniques depend on where exactly the encoded string will be placed, as browsers apply decoding based on the context in which the content is found. For example, URL encoding is supported in href tag URLs but not in tag names. All the evasion methods described below are often combined with some form of encoding.
For example, to fool filters that only look for typical ASCII patterns, you might replace:
ascriptΪlert(documentˬookie). Note that in this example, you could also skip any or all semicolons.
If the filter knows how to recognize simpler encoding attempts, another trick is to use decimal encoding with padding and skip semicolons. For example, the string
alert is equivalent to
Case manipulation and character insertion
If the filter is case-sensitive, it may be fooled if you use a different case than the one that is expected. For example, if a filter only matches
<script>, you could use
<Script> or even
Additionally, modern web browsers usually ignore any extra whitespace characters (spaces, tabs, newlines, and carriage returns) inside HTML tags, so you could also write a script tag as
<script[\x13]>. You can also attempt to insert a null byte anywhere in the string, for example,
Fooling regular expressions
Sometimes bypassing a filter is a matter of fooling the regex. For example, you can use fake tags with angle brackets:
<script a=">" src="http://example.com/xss.jpg"></script>. If the regular expression does not cover this case, it will assume that the script tag ends with the first closing bracket. Also, note how the file in this payload is named to mimic a JPG image and fool filters that look for specific file extensions.
Using atypical event handlers
Tricks with tags and attributes
Some filters focus only on common tags and can be bypassed by using lesser-known tags as XSS vectors, such as
<svg>. However, filters may also forget to include such obvious tags as
Using atypical delimiters
<script src=test`onload=`alert(document.cookie)></script>. Filters may also be tricked by extra angle brackets and slashes (comment characters), as in
<<script>alert(document.cookie)//<</script>. In fact, modern browsers are often so tolerant that they might even helpfully render the following code properly:
<iframe src=http://xss.example.com/xss.html <.
For the first whitespace after the tag name, the choice of delimiters is even greater. For example, you could replace it with a single slash:
Making other deliberate mistakes
Deliberate mistakes can help to bypass many filters without affecting how the page is rendered because browsers will attempt to correct them based on the context. This is especially true when you use quotes in the wrong place or order, or “forget” to close them.
A very simple example of deliberate quote confusion is
<input type="text" name="test" value="><script>alert("xss")</script>. The unclosed quote after
value may fool the filter that expects valid syntax, but the code will still be executed because most browsers will fix it internally and treat the quote as closed.
Another deliberate error used to fool filters is adding junk content after the tag name. Many modern browsers will completely ignore any characters after a valid tag name, making it possible to use
<script/anything> instead of
<script> (also note the use of the single slash delimiter described in the previous section).
Combining multiple methods
In practice, the above methods can be combined to make evasion more effective. For example, you could use meta tags such as refresh along with base64 encoding:
You will find some XSS filter evasion tutorials online that have not been updated for many years and list techniques that no longer work in modern browsers. As a curiosity, here are some of the most interesting techniques found in old cheat sheets that only work in very old browsers (in some cases, even as old as Netscape):
- Using stylesheet links:
- Using CSS:
- Using eval and fromCharCode to escape disallowed content, for example,
- Using VBScript in an image:
<img src='vbscript:msgbox("warning")'>or using livescript
How to prevent XSS filter evasion?
In theory, it is possible to create a nearly foolproof XSS filter, but it would be enormously complex and hard to maintain – and someone would eventually come up with a new bypass technique anyway. That is why proper character escaping is the easier and recommended method of preventing XSS attacks because no matter how complex your XSS filter or how good your WAF, they will never fully guarantee that a clever hacker won’t find a way in.
If, for some reason, you can’t use escaping, you can find XSS filtering projects on GitHub and in other open-source repositories to detect known XSS filter evasion methods. Before you decide to use one, though, make sure the project is still actively maintained (for example, don’t use a filter like php-antixss that was last updated in 2010).
Frequently asked questions
What is XSS filter evasion?
XSS filter evasion is a collective cybersecurity term for methods that hackers use to bypass XSS filters in web applications. XSS filter evasion relies on various tricks to avoid search and detection patterns in filters, usually by fooling regular expressions.
Learn more about methods used to prevent cross-site scripting.
How dangerous is XSS filter evasion?
If your filter is susceptible to known XSS filter evasion techniques, it can be considered useless. And even assuming your current filter protects against known and published evasion techniques, there is no guarantee that new evasion techniques won’t be found and used to bypass it, allowing for successful XSS attacks against your site.
Read more about the dangers of XSS filter evasion in our blog post.
How to prevent XSS filter evasion?
Read more about HTTP security headers, which can help mitigate XSS exploitation.
Related blog posts
Written by: Tomasz Andrzej Nidecki, reviewed by: Benjamin Daniel Mussler