Unterminated XSS
I recently came up against the following injection (simplified for the purposes of this post):
https://example.com/foo.php?r=foobar
This is Injection into a JavaScript object initializer.
OK… let’s try the obvious:
https://example.com/foo.php?r=foobar"}; alert('xss');
which renders
Don’t forget to use that scrollbar! And ofc the parameters are percent encoded, but shown here plain for your enjoyment.
However, no popup. Chrome developer tools said
Uncaught SyntaxError: Invalid or unexpected token
and Firefox’s said:
SyntaxError: unterminated string literal
So lets try removing the trailing script by commenting it out:
https://example.com/foo.php?r=foobar"}; alert('xss');//
but this rendered
Our old friend, filtering. We meet again.
OK, let’s try terminating the script tag and making a new one:
https://example.com/foo.php?r=foobar</script><script>alert('xss')</script>
but this rendered
Hmm, not quite what we wanted. Wonder if that’s a genuine filter case, or whether the //
comment filter is going wrong? Or this filter is intended, and the other is a side-effect. Who knows? Whatever.
OK, so <
seems to work, but we can’t comment as /
is filtered. I was stumped for a while, lunchtime came, I went for a Boots sandwich and then came back to my desk to sulk.
Then it hit me. If JavaScript comments don’t work, how about HTML comments?
https://example.com/foo.php?r=foobar"}; alert('xss');<!--
which rendered
Success!
Why does this work? See the spec.