17

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
  • 301
  • 2
  • 11
  • 1
    The related highly voted post at stackoverflow from 07/2014 should explain this: [Is JSON Hijacking still an issue in modern browsers?](http://stackoverflow.com/questions/16289894/is-json-hijacking-still-an-issue-in-modern-browsers). – Steffen Ullrich Apr 02 '17 at 16:52
  • @SteffenUllrich I read that discussion and I understand that JSON hijacking was fixed by the browsers (not sure about the UTF-7 version with the attacker having control over a JSON attribute), but I didn't fully understand **how** browsers decided to handle that. – fbid Apr 02 '17 at 18:26
  • the relevant part of the answer is the one about changes in the spec which clarified the behavior of object constructors and what can be done with setters and forbid this way the specific attacks used in JSON hijacking. – Steffen Ullrich Apr 02 '17 at 19:04
  • 1
    Related on Stack Overflow: [Why does Google prepend while(1); to their JSON responses?](https://stackoverflow.com/q/2669690/3258851) – Marc.2377 Dec 10 '18 at 18:11

1 Answers1

6

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,658
  • 10
  • 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?](https://stackoverflow.com/a/3147804/712526) – 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 ` – 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