Cross-site scripting (XSS) is one of the three most exploited security vulnerability on the web.
A XSS vulnerability enables attackers to inject client-side script into a Web page viewed by other users.
Although it's a client-side attack it can be critical and lead to a full compromise.
Unfortunately XSS vulnerabilities are often misunderstood and overlooked.
Along the years pentesters have developed stealth tricks to evade XSS filters.
This cheat sheet is focused on providing guidance against these filters.
PHP XSS filters evasion
PHP is probably the most popular server-side scripting language designed for online web development.
By default PHP doesn't escape HTML tags from user controlled input.
If the developer of a web application doesn't properly sanitize user controlled input, it can lead to a vulnerability.
Some developers are using the
preg_replace functions to remove
This is bad practice because other HTML tags such as
The trick to evade a replace filter is to understand how it works and to take advantage of its weakness.
The code below takes the author parameter, remove all occurrences of
script no matter what the case is and print the result.
<?php echo 'Author: ' . preg_replace('/script/i', '', $_GET['author']); /* Example output for …?author=Alice Author: Alice */ ?>
An attacker can easily leverage this vulnerable code by splitting the tag.
The output for
Author: <script>alert('XSS')</script> and the script will execute.
htmlentities is a far better choice, but in some situations it can still lead to a vulnerability.
The code below takes the user parameter, removes all occurrences of script and prints the result.
<?php echo "Profile picture <img alt='Profile' src='/profiles/".htmlentities($_GET["user"]).".jpg' />"; /* Example output for …?user=Bob Profile picture <img alt='Profile' src='/profiles/Bob.jpg' /> */ ?>
By default the
htmlentities function doesn't convert single quotes to HTML character entities.
Then we can use the
The request to
…?user=x' onerror='alert("XSS") will set the
src of the
img tag to x.
Because the picture doesn't exists the
onerror event is triggered and the attacker code will execute.
The data URI scheme is a (Uniform Resource Identifier) scheme that provides a way to include data in-line in web pages as if they were external resources.
Data URI syntax
The syntax of data URIs was defined RFC 2397, published in August 1998.
data:[<media type>][;charset=<character set>][;base64],<data>
An HTML fragment embedding a picture of Wiremask.
<img src="data:image/bmp;base64,Qk1+AAAAAAAAAD4AAAAoAAAAPAAAAAgAAAABAAEAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wDOduQTZPIbkM52zPIm99swxHbM8iYHynCUNhzypmcYcJW2zDCHbjjwsbbs8ccO+nCxtuzxx477MDmWDDHnnhuQ" alt="wiremask" />
Data URIs can be used with just a few HTML tags.
The code below takes the video parameter, converts all special characters to HTML entities with the
htmlspecialchars function and prints the result.
<?php echo 'Video: <object width="800" height="600" data="'.htmlspecialchars($_GET['video']).'"></object>'; /* Example output for ?video=Wizzy.swf Video: <object width="800" height="600" data="Wizzy.swf"></object> */ ?>
An attacker can encode the payload
<script>alert("XSS")</script> to Base64 and create an URL
The media type of the Data URI is set to text/html which means that the object will decode the Base64 encoded payload and execute its content.
There is another way to exploit XSS vulnerabilities through
If the page encoding is UTF-7 or if the attacker is able to control the page encoding, then the following UTF-7 encoded payload
+ADw-script+AD4-alert('XSS')+ADsAPA-/script+AD4- will execute.