XSS technique without parentheses
Tuesday, 1 May 2012
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.
No. 1 — May 1st, 2012 at 12:50 pm
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
No. 2 — May 1st, 2012 at 12:58 pm
Yeah setter is dead 🙁
location=name is nicer
No. 3 — May 1st, 2012 at 1:10 pm
The default scope is actually “undefined” if you are running under the Strict Mode. Otherwise, it’s “window”, as you mentioned.
No. 4 — May 1st, 2012 at 1:22 pm
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
No. 5 — May 1st, 2012 at 1:35 pm
@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.
No. 6 — May 1st, 2012 at 8:04 pm
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.)
No. 7 — May 2nd, 2012 at 12:54 am
Great use of the throw! and i <3 your blog, keep it up!
No. 8 — May 2nd, 2012 at 9:53 am
Nice tricks !
maybe you have a list of bypassed WAF (default rules)?
No. 9 — May 2nd, 2012 at 4:24 pm
Using onerror all the time. It’s a good way to bypass web application firewalls. For anyone who needs XSS without using whitespaces:
No. 10 — May 2nd, 2012 at 4:24 pm
img/src=”x”onerror=alert(‘x’)
No. 11 — May 2nd, 2012 at 8:00 pm
One problem, this isn’t a real exploit. Its just a PoC, its completely and totally useless to an attacker.
Interesting, but totally useless.
No. 12 — May 2nd, 2012 at 9:02 pm
@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.
No. 13 — May 8th, 2012 at 4:48 pm
@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`).