Skip to content

encoding

Inside a script block

The one context where HTML escaping does nothing at all.

Interpolating a value into a script block is a completely ordinary thing to do — a page that needs to know who is signed in has to get that from somewhere — and it is the context where every habit from the other three lets you down. Angle brackets are not special inside a script. Escaping them changes nothing about what the JavaScript does.

What is special is the string delimiter the value sits inside, and the six characters </script — which end the element wherever they appear, including in the middle of a string literal.

  • GET /me/page

    The display name reaches a script block here, safely. Look at how it was encoded rather than at whether it was.

This app is honest about what it can and cannot prove here. The tokenizer that decides whether a payload reached a script context is an HTML tokenizer, so it sees a value that closes the element and it does not see one that merely breaks out of a JavaScript string. Proving the second needs a JavaScript interpreter, which is filed and is not in this release.

The consequence is worth stating plainly: a witness for this class has to leave the script element. That is a real payload rather than a contrivance, and it is also less than the whole truth about the defect.

This build

id.example.com

Nothing sent yet. Every request goes to the application in this tab and nowhere else.