While researching the issue of JSON vs XML, I came across this question. Now one of the reasons to prefer JSON was listed as the ease of conversion in Javascript, namely with the eval()
. Now this immediately struck me as potentially problematic from a security perspective.
So I started doing some research into the security aspects of JSON and across this blog post about how JSON is not as safe as people think it is. This part stuck out:
Update: If you are doing JSON 100% properly, then you will only have objects at the top level. Arrays, Strings, Numbers, etc will all be wrapped. A JSON object will then fail to eval() because the JavaScript interpreter will think it's looking at a block rather than an object. This goes a long way to protecting against these attacks, however it's still best to protect your secure data with un-predictable URLs.
Ok, so that's a good rule to start with: JSON objects at the top level should always be objects and never arrays, numbers or strings. Sounds like a good rule to me.
Is there anything else to do or avoid when it comes to JSON and AJAX related security?
The last part of the above quote mentions unpredictable URLs. Does anyone have more information on this, especially how you do it in PHP? I'm far more experienced in Java than PHP and in Java it's easy (in that you can map a whole range of URLs to a single servlet) whereas all the PHP I've done have mapped a single URL to the PHP script.
Also, how exactly do you use unpredictable URLs to increase security?
JSON alone is not much of a threat. After all, it's only a data-interchange format. The real security concerns with JSON arise in the way that it is used. If misused, JSON-based applications can become vulnerable to attacks such as JSON hijacking and JSON injection.
JavaScript Object Notation (JSON) security performs deep inspection of incoming packets/requests for web applications that use the JSON protocol to exchange data over HTTP.
JSON does not provide namespace support while XML provides namespaces support. JSON has no display capabilities whereas XML offers the capability to display data. JSON is less secured whereas XML is more secure compared to JSON. JSON supports only UTF-8 encoding whereas XML supports various encoding formats.
There are a number of security attacks against JSON, especially XSRF.
The vulnerability occurs when a web service uses cookies for authentication, and responds with a JSON array containing sensitive data in response to a GET request.
If an attacker can trick a user who is logged into a service, naive-webapp.com, into visiting their site (or any site that embeds an IFRAME they control, e.g. via embedded ads) then they can insert a <script>
tag with a SRC to the naive-webapp.com, and potentially steal the user's data. This depends on a javascript quirk with the JavaScript Array
constructor like this:
<script> // Overload the Array constructor so we can intercept data var stolenArrays = []; var RealArray = Array; Array = function () { var arr = RealArray.apply(arguments); stolenArrays.push(arr); return arr; } </script> <!-- even though the attacker can't access the cookies, - he can cause the browser to send them to naive-webapp.com --> <script src="//naive-webapp.com/..."></script> <script> // now stolenArrays contains any data from the parsed JSON </script>
EcmaScript 5 has fixed the confusing behavior that caused []
to look up Array
on the global object and many modern browsers are no longer susceptible to this attack.
Incidentally, Oil is wrong about unpredictable URLs. Cryptographically secure random identifiers in URLs are a fine way to protect resources. Identity based security is not a panacea as Oil suggests. See http://waterken.sourceforge.net/ for an example of a secure distributed application scheme based on cryptographically secure identifiers in URLs that does not require a concept of identity.
EDIT:
When considering JSON vs XML, you should be aware of XML specific attack vectors as well.
XXE, XML External entities attacks, use crafted XML to access file system and network resources through the firewall.
<!DOCTYPE root [ <!ENTITY foo SYSTEM "file:///c:/winnt/win.ini"> ]> ... <in>&foo;</in>
The Application embeds the input (parameter "in", which contains the win.ini file) to the web service response.
The main security hole from the blog (CSRF), is not JSON specific. It's just as big a hole using XML instead. Indeed, it's just as bad with no asynchronous calls at all; regular links are just as vulnerable.
When people talk about unique URLs, they generally DON'T mean http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement. Instead, it's more common to make something else about the request unique; namely a value in the FORM post, or a URL parameter.
Usually this involves a random token inserted into the FORM on the server side, and then checked when a request is made.
The array/object thing is news to me:
Script-Tags: The attacker can embed a script tag pointing at a remote server and the browser will effectively eval() the reply for you, however it throws away the response and since JSON is all response, you're safe.
In that case, your site doesn't need to use JSON at all to be vulnerable. But yeah, if an attacker can insert random HTML into your site, you're toast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With