18

I understand JSON Hijacking vulnerabilities have been fixed in all modern browsers, but how exactly?

There are many articles that talk about techniques to prevent JSON Hijacking attacks (i.e. prepending while(1); like Google does), but no one has explained if they still need to be implemented in a web application nowadays (obviously assuming users won't be using the app with very old browsers).

Should returning JSON data as array literals be considered a security risk nowadays?

jpaugh
  • 161
  • 1
  • 8
fbid
  • 311
  • 2
  • 11

1 Answers1

8

The JSON issue that led google to prepend while was a same-origin breakdown in early versions of firefox (1.5 and 2b specifically) where the JSON file could be loaded as a normal script tag from off-site, and have its data reachable.

Normally JSON files don't "tell" the JS engine to do anything if loaded as a script, so they have/leave no reference to their data structures. JS's security is reference-based, so that assumption is fine. JSON Object literals ({})are actually an ambiguity to JS's engine since they look like code braces, causing those to syntax error. The problem with old FF was that one could use obscure runtime modifications that caused Array literals to execute some other code when parsed/created. That other code could introspectively reach the array's contents, which was a bug.

There were related issues with XML, as firefox considered some XML shapes to be valid JavaScript(tm) using FF's E4X extension (Ecmascript4XML). IE had some issues with non-js content being loaded as a script, erroring out, but revealing the contents to a pre-applied global error handler, which reported the source of the "code" causing the issue.

Since there are now viable safe ways of grabbing remote JSON content, the vulnerabilities of obsolete browsers and JSONp/eval() exploits no longer apply to loading content. If you try to load a valid JSON resource as a script, you cannot reach the contents from other JS.

Lastly, I don't think this actually has very much to do with security; php, curl, python etc don't give a hoot about the browser's rules; if data is out there it's out there. The only thing the same-origin policy does in that regard is prevent run of the mill "deep-linking" resource stealing of non-secret data.

dandavis
  • 2,693
  • 11
  • 16
  • 3
    This answer (currently) is blurring the two sides of the security question. The points you raise are about a client trying to safely load JSON data from a cooperating remote source. However, JSON Hijacking and the while(1); prevention were about enforcing the cross-origin policy - the vulnerability allowed webpages to read JSON data from a non-cooperating resource. – cloudfeet Apr 03 '17 at 21:54
  • @cloudfeet: the "while" part was added after i answered, and i mentioned the "really really old" issue of stealing cross-domain resources, but in light of the edit clarifying the main concern, i'll expand on that part. – dandavis Apr 03 '17 at 22:48
  • This answer ignores the possibility of stealing data by redefining the global Object or Array constructors. Cf. Why do people put code like for(;;); in front of json responses? – jpaugh Apr 09 '18 at 21:26
  • @jpaugh: Not ignored, that's addressed in the first sentence. You can't steal data like since ~10 years ago... – dandavis Apr 10 '18 at 01:02
  • 1
    The last paragraph here seems wrong to me. One issue is that a cross-origin <script> is fetched with the user's cookies (which the attacker does not have and can't get, and therefore can't feed to "php, curl, python etc"). Another is that if the user is on an intranet, behind a firewall, that <script> can hit URLs that are firewalled off from the Internet (i.e. not "out there"). – Jason Orendorff Feb 25 '20 at 20:22
  • 1
    Amazingly, data leakage still exists and is still getting attention from standards bodies and browser vendors in 2020. https://github.com/whatwg/html/issues/958#issuecomment-585895989 – Jason Orendorff Feb 25 '20 at 20:24