XSS technique without parentheses

This is a very old technique I discovered years ago which I used to bypass a filter and it’s pretty awesome. It might come in handy to bypass a WAF or filter since it’s not public until now. First you need to understand (which you probably do) that the window object is the default object in JavaScript and every time you execute code it’s like you’ve run a with statement on the window if your not more specific. So stuff like onload is really window.onload and so on lets see if you can guess what comes next….

So in JavaScript we have a onerror handler which is also on the window object, this means if we assign a function to onerror we can call it by generating a JavaScript error! How do we generate a JavaScript error? Throw is a nice way, this means throw can pass an argument to a function you can create some pretty awesome crazy looking JavaScript.


onerror=alert;throw 1;

This works on every browser apart from Firefox *, Safari and IE will just call the function with the argument but Chrome and Opera add uncaught to the argument. This is no big deal though since we can just modify it slightly and use a different object as an argument such as a string.


onerror=eval;throw'=alert\x281\x29';

Thought I’d post this before this technique gets lost forever and I forget about it pretty awesome XSS eh? :)

* Does actually work in Firefox. My site was disabling the error handling.

13 Responses to “XSS technique without parentheses”

  1. albino writes:

    Nice! I needed a paren-less XSS just the other day, and ended up trying loads of tacky options;

    document.domain=name // is nice but chrome only

    a setter=alert,a=1; //doesn’t seem to work nowadays

    location=’javascript://’+location.hash //ended up using this

  2. Gareth Heyes writes:

    Yeah setter is dead :(

    location=name is nicer

  3. Kai Sellgren writes:

    The default scope is actually “undefined” if you are running under the Strict Mode. Otherwise, it’s “window”, as you mentioned.

  4. albino writes:

    Indeed, I wonder if there’s a way to set the window name on a POST-only XSS to a page with X-Frame-Options: deny

  5. Gareth Heyes writes:

    @Kai

    use strict changes the “this” value to undefined but the scoping still counts.

    !function(){
    ‘use strict';
    alert(onerror)//is null since the scope is still window
    }();

    I don’t think this technique will work on strict mode but I haven’t checked extensively.

    @albino

    Yes you can use regular anchor links on some browsers, simply setting the current window name will be inherited x-domain if not fixed yet.

  6. matt writes:

    I use something like: document.body.innerHTML=location.hash; Then use #<img src=x onerror=… or what ever other code/script you want in the hash part of the url. The other good thing about this type of attack is that the payload is in part of the url hash and is therefore never sent to the server. (no servers logs of actual attack payload.)

  7. Linux Ninjas writes:

    Great use of the throw! and i <3 your blog, keep it up!

  8. Karim Slamani writes:

    Nice tricks !
    maybe you have a list of bypassed WAF (default rules)?

  9. Jean Pascal Pereira writes:

    Using onerror all the time. It’s a good way to bypass web application firewalls. For anyone who needs XSS without using whitespaces:

  10. Jean Pascal Pereira writes:

    img/src=”x”onerror=alert(‘x’)

  11. Mike writes:

    One problem, this isn’t a real exploit. Its just a PoC, its completely and totally useless to an attacker.

    Interesting, but totally useless.

  12. Gareth Heyes writes:

    @Mike

    What on earth are you talking about? As I said I used it to bypass a filter so it wasn’t totally useless. It is also called imagination, you really don’t get it do you?

    I don’t post this stuff to create cookie stealing worms, I post the technique. The point of creation of the technique is all I care about. The challenge of creating something new that others didn’t find is what I enjoy.

  13. Kai Sellgren writes:

    @Gareth:

    By “scope” I was referring to the value of `this`. Maybe I used improper terminology. Sure, still in case of “use strict”, you may access variables of outer scopes (eventually leading to `window`).