First of all I must say that there are web applications which get output escaping right. I had a confrontation recently with one. I could store malicious attack strings in the database that were shown on the UI, still I couldn’t evade the output escaping even though I tried really hard. At the end I had to accept that the JavaScript generated UI was too good.

But it didn’t last long. During a sleepless night as my head span around of exploits and evil attack scenarios the IDEA came. The whole communication between the client and server was in JSON using XMLHttpRequest. My attack strings were still unescaped in the JSON response and the client side JavaScript did all the dirty work. That would have been still alright even though that it doesn’t comply with the security in-depth theorem. And here comes the BUT: in some responses the HTTP Content-type header was incorrectly set to text/HTML instead of the application/json and that is just great. It means that tha attacker only needs a URL that will return the malicious XSS string with the text/HTML content type and he could immediately start to send it to users.

I’m sure most of you have already figured out the trick but let me clearify it. When the browser sees the Content-type: text/HTML it will do anything to render the response as HTML. It will be so glad when it finds the little piece of <script> tag in the middle of the uninteresting JSON, that it will immediately render it hence the evil JavaScript gets executed. From this point it only depends on the JavaScript code whether the user will realise what happened or not. The moral of the story is that it doesn’t metter how good written your application is because if you make just one mistake that is just enought for the attackers.

To let you take something away from the story here are the mitigations that could have stopped this attack:

  • Validate and escape input before saving it in the database.
  • Set the Content-type header properly.