JSON and XML both serves as a medium for server client communication. So, why are security concerns with one and not other?
The fundamental difference is that JSON(JavaScript Object Notation) as name suggests is very near and dear to JavaScript and hence in design of some JavaScript methods and functionalities, JavaScript treats JSON strings as it's cup of tea and tries to interpret it directly, which give workarounds to attackers to fool JavaScript interpreter to run malicious JavaScript embedded in the string causing vulnerabilities, while XML has to go through a parsing stage to be parsed into an object making it harder to attack with.
2 such JavaScript functionalities are eval() method and tag.
How does these create a security vulnerabilities?
Although web follows the same-origin policy, historically there have been loopholes found to bypass it and malicious sites use them to send cross site request to authenticated user website, breaking the intent of same-origin policy.
Example :
In spite of same-origin policy being in place, web has allowed some tags like <img> <script>
to make cross origin GET requests.
let us say you are on a website www.authenticatedwebsite.com
, but lured to open a www.malicious.com
which has a tag in its html
<script src="www.authenticatedwebsite.com/get-user-order-history" />
Attacker from www.malicious.com
use this script tag behavior to access your private data from www.authenticatedwebsite.com
.
Now, how does a script tag which is calling a src url, store the url response to a javascript object[to perform operations like POSTing it to malicious site server]?
Here comes the role of JSON and XML proves out to be safer here. As JavaScript understands JSON pretty well, some JavaScript interpreters interprets naked JSON string as a valid JavaScript and run it.
What can running a JSON string potentially do, as it is still not assigned to a variable?
This can be achieved by another fancy hack.
If the returned JSON string represents an array. JavaScript will try to run the constructor of Array class. Now it is possible to override the constructor of Array in JavaScript. You can do something like :
Array = function(){ yourObject = this };
This is basically overriding JavaScript Array constructor, such that whenever JavaScript calls constructor, the current interpreted array is assigned to yourObject, thus giving malicious website access to your private data.
Now, this attack can be used with variants of JSON strings, with more sophisticated hacks.
Although above represents a valid scenario, where JSON can be dangerous as a return format of your GET APIs. This is actually possible in only some versions of some browsers, and as far as I know, all modern versions of famous browsers have mitigated it, but as your user base can be divided across versions of browsers, you need to be careful with GET APIs giving out private information in naked JSON format.
One of the technique used to circumvent this is adding a while(true) in front of your JSON response strings, which will never allow JavaScript interpreter to reach to the actual string. But it creates parsing overhead on your client side.
Another possible mishaps that JSON can cause is use of eval()
method on browser client side to parse JSON. As eval()
has capability to run script, if your JSON string contains some hidden script which eval()
runs and perform dangerous actions what attacker injected script asks it to do, can prove out to be security issues for your system. But as others have mentioned, this attack can be easily prevented by strictly abandoning eval()
method as your JSON parser everywhere in client code. This vulnerability plug in is highly important for websites which stores user generated content.