Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I have a web service that takes POST data (JSON) and returns part of the request object in the JSON response.

This is open to XSS if the response is rendered as HTML by the browser since someone could add arbitrary HTML to the request object.

What is the standard way to mitigate this? Current options I can think of are:

  • Only allow requests with X-Requested-With: XMLHttpRequest header to stop attacks that rely on non-ajax requests to my service
  • Send the response with content type application/json and hope the browser refuses to render this as HTML
  • Encode unsafe characters in the response (how do I do this? using \uxxxx?)

I have been unable to find a concrete reference on this.

share|improve this question
add comment

2 Answers

Encode unsafe characters in the response (how do I do this? using \uxxxx?)

Yes. < to \u003C in particular.

There may be an option in your JSON encoder to do this already (eg in PHP, JSON_HEX_TAG); otherwise, it's a simple job to do a string replace after the encoding. (This is safe as there is no place a < may legally be used in JSON other than in a string literal.) At this point you can also include the leading chaff to prevent cross-origin script inclusion.

I would send as application/json as a matter of correctness, but I wouldn't trust every older browser to necessarily honour it. Relying on the X-Requested-With header is generally problematic as it doesn't play well with caching, though that may not be a concern for you.

share|improve this answer
    
As noted by Erlend, if you're going to use Content-Type: application/json as a security measure, then it makes sense to serve X-Content-Type-Options: nosniff as well, since this will protect IE 8 and 9 users against the MIME sniffing exploit I describe in the second half of this answer. (Of course, if you're already HTML-encoding all < characters then this is redundant, as is the application/json header itself from a security perspective.) –  Mark Amery Jan 19 at 12:05
add comment

Set the Content-Type to application/json, and set X-Content-Type-Options: nosniff (the last header instructs the browser to use the given content-type - no extra guessing). You could even considef adding a Content-Disposition: attachment header. This will be ignored by XHR requests, but cause the download dialog to pop if an attacker tries to trick a user into opening it directly in the browser.

You could also have a look at: http://erlend.oftedal.no/blog/?blogid=127 and http://erlend.oftedal.no/blog/?blogid=134

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.