On Friday 26th of August at 12:25 I published an XSS puzzler on twitter:
At 14:30 the first valid solution was delivered by @steike, and I got some valid solutions from others as well, but these were all rather long.
At 21:19 Masato Kinugawa submitted a 28 character solution which at least to my knowledge is the shortest vector possible:
Mario quickly followed, and as can be seen on the hall of fame, several others submitted the same or a very similar solution of 28 characters.
Dissecting the vulnerability
This works, but it becomes a rather long vector as + has to be encoded into %2B. The code above would take the String class’ constructor, and then take the constructor of the constructor, which is Function. It would then call Function with “alert(1)”, which would create a function. The resulting function is then called with the remaining ().
Mathias Bynens wrote two blog posts about valid identifiers in ES5 and ES6. These blog posts show us how we can use unicode escapes as a part of the names of a function we want to invoke. And indeed I got several submissions using the ES5 method:
Masato Kinugawa was the first one to submit with ES6:
This is quite clever as there are no two letters next to each other.
The last piece of the puzzle was to get rid of the trailing:
This can be solved by reading up on some specs:
The new line has to be URL encoded though, so the final vector becomes:
I’d also like to give a mention to @izanbf1803 who solved the challenge with 28 chars, and is only 15 years old.