Search code examples
ruby-on-railsjsonember.jsxssburp

Burp reporting XSS vulnerability in unescaped HTML in JSON response


I have a Rails/Ember one-page app. Burp reports that

The value of the 'content_type' JSON parameter is copied into the HTML document as plain text between tags. The payload da80balert(1)4f31e was submitted in the content_type JSON parameter. This input was echoed unmodified in the application's response.

I can't quite parse this message referring to "is copied into" and "was submitted" in, but basically what is happening is:

  1. A PUT or POST from the client contains ...<script>...</script>... in some field.
  2. The server handles this request, and sends back the created object in JSON format, which includes the string in question
  3. The client then displays that string, using the standard Embers/Handlebars {{content_type}}, which HTML-escapes the string and inserts it into the DOM, so the browser displays it on the screen as originally entered (and of course does NOT execute it).

So yes, the input was indeed echoed unmodified in the application's response. However, the application's response was not HTML, in which case there would indeed be a problem, but JSON, containing strings which when referred to by Handlebars will always be escaped properly for proper display in the browser.

So my question is, is this in fact a vulnerability? I have taken great care with my Ember app and can prove that no data from JSON objects is ever inserted "raw" into the DOM. Or is this a false positive given rise to by the mere fact the unescaped string may be found in the response if looked for using an unintelligent string comparison, not taking into account the fact that the JSON will be processed/escaped by the client-side framework?

To put it a different way, in a classic webapp spitting out HTML from the server, we know that user input such as the above must be escaped/sanitized properly. Unsanitized data "on the wire" in and of itself represents a vulnerability. However, in a one-page app based on JSON coming back from the server, the escaping/sanitization occurs in the client; the JSON on the "wire" may contain unsanitized data, and this is as expected. Am I missing something here?


Solution

  • There are subtle ways in which you can trick IE9 and older into treating JSON as HTML. So even if the server's response has a Content-Type header of application/json, IE will second guess it. This is called content type sniffing, and can be disabled by adding the X-Content-Type-Options: nosniff header. JSON is not an executable format so your understanding is correct.

    I did a demo of this exact problem in my talk on securing single page web apps at OWASP AppSec EU 2013 which someone put up on youtube here: http://m.youtube.com/watch?v=Femsrx0m9bU