8

As far as I know it is considered bad practice to eval() JSON objects in JavaScript, because of security. I can understand this concern if the JSON comes from another server.

But if the JSON is provided by my own server and is created using PHP's json_encode (let us assume it is not buggy), is it legitimate to simply use eval() to read the JSON in JS or are there any security problem I currently can't think of?

I really don't want to deal with dynamically loading a JSON parser and would be glad to simply use eval().

PS: I will obviously use the native JSON object if it is available, but want to fall back to eval() for IE/Opera.

NikiC
  • 100,734
  • 37
  • 191
  • 225
  • 2
    JavaScript’s `eval` will evaluate *any* JavaScript code and not just the small subset that is equal to JSON. – Gumbo Nov 24 '10 at 19:16
  • Of course it's good to encode your data, but you're not going to maintain the same codebase forever (hopefully), eventually someone else will need to maintain it, and what if there's that one new part of a bug fix that someone put it and it doesn't call the encoding method, or it does call it but at the wrong spot -- and it opens a security vulnerability -- having the second safety net there as a fallback could be the difference between embarrassing PR announcement(s), expensive lawsuit(s) and legal consequences, versus a simple code patch to fix the middle-tier safety net. – BrainSlugs83 Jul 23 '14 at 21:20
  • The other thing to consider is also maintainability -- abiding by well known standards will make it easier to transition ownership of the code on to another developer/team, etc. when the time comes -- which is pretty powerful in it's own right, but to put that in the context of security: developers who know what their code is doing and how it works (because it uses the standardized best practices for your particular niche) are going to be less likely to put in code that derps things up and adds new security flaws by accident, etc. – BrainSlugs83 Jul 23 '14 at 21:23

6 Answers6

9

In your scenario, the question becomes, where is PHP getting the javascript to execute from? Is that channel secure, and free from potential user manipulation? What if you don't control that channel directly?

Matthew Vines
  • 27,253
  • 7
  • 76
  • 97
  • I don't know what the user can manipulate here. I properly construct the output with `json_encode`. The user thus can only manipulate the contents of the JSON, not it's syntax. Thus I don't see a way how he could inject arbitrary JS. – NikiC Nov 24 '10 at 19:18
  • 1
    @Gumbo: A man-in-the-middle could directly manipulate the JavaScript. Why bother hacking the JSON if you can hack the JS? – NikiC Nov 24 '10 at 19:21
  • @nikic: It’s just a possible scenario. – Gumbo Nov 24 '10 at 19:22
  • @Gumbo: What do you mean by that? So is it an issue or is it not? – NikiC Nov 24 '10 at 19:24
  • @Gumbo: Would you bother to explain why? In my eyes it is by far simpler to manipulate the JavaScript directly than to manipulate the JSON. Or at least I think that if you can manipulate the JSON you can manipulate the JS, too ;) – NikiC Nov 24 '10 at 19:28
  • 1
    No, definitely. And if the JSON is manipulated, you might not have a way to detect it, leading to far more badness in your future. – wlangstroth Nov 24 '10 at 19:54
7

There are a number of ways that your security may be compromised.

  • Man in the middle attacks could theoretically alter the contents of data being delivered to the client.
  • Your server traffic could be intercepted elsewhere and different content could be provided (not quite the same as a MIM attack)
  • Your server could be compromised and the data source could be tampered with.

and these are just the simple examples. XSS is nasty.

"an ounce of prevention is worth a pound of cure"

zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • 1
    If the server is compromised, the attacker can modify the original page. – SLaks Nov 24 '10 at 19:43
  • @zzzzBov: Could you please elaborate? If someone has taken control over my connection he can manipulate anything - and it's far more effective to manipulate the JS rather than the JSON. – NikiC Nov 24 '10 at 19:50
  • @nikic the trick to successful MIM and XSS attacks is to not be noticed. The longer you can retain control the more information can be gathered. If a script can be injected into a page that distributes a virus or collects personal information, the owner of said script would probably rather have it stick around for a while, rather than be removed by the site owner. Just because someone has access to part of a server, doesn't mean they have root access; it really depends on how everything is set up. – zzzzBov Nov 24 '10 at 19:55
  • @zzzzBov: Inserting some small script into my JS to collect user-information seems hard to notice. At least at least as hard as putting the same into my JSON... And I don't see a way how somebody could control my JSON but not my JS... – NikiC Nov 24 '10 at 20:00
  • @nikic I don't know how your server is organized, but I'm trying to give some generic answers. When I create a web project that's AJAX enabled I try to separate the page source from the JSON source. If I were to then move my JSON to a subdomain (ajax.whatever.com or json.whatever.com) it may be possible for an attacker to gain access to that subdomain without having access to the entire server. I know this is not likely what you're doing, but I'm trying to give generic examples. – zzzzBov Nov 24 '10 at 20:04
  • @zzzzBov: I am using only one domain and one system to serve both JSON and other data. So is your point only of importance if an attacker might get access to the JSON but not to the rest of the JS? – NikiC Nov 24 '10 at 20:11
  • @nikic ask yourself this question: Might an attack get access to some part of my website? If the answer is yes, then take every preventative measure in your arsenal. If the answer is no, publish your works as you probably deserve about five bajillion awards for security. – zzzzBov Nov 24 '10 at 20:18
  • @zzzzBov: I get your point. Even though I don't really believe in an attacker gaining access to my JSON without gaining access to my JS, it obviously could be possible. Thanks for your help +1. – NikiC Nov 24 '10 at 20:28
3

Besides the obvious security issues:

  1. Native JSON is faster
  2. You don't need to "load" a JSON parser it's just another function call to the JavaScript engine
Ivo Wetzel
  • 46,459
  • 16
  • 98
  • 112
  • 1
    Well, *some* people out there still want to have support for IE and Opera - I am one of them. Obviously, if the native JSON object is available, I will call it. – NikiC Nov 24 '10 at 19:19
  • 1
    Opera? Which version of Opera are you using? Opera has JSON support for nearly a year now. Also, you can still fallback to Crockfords JSON which *does perform validation* before passing the stuff to eval. – Ivo Wetzel Nov 24 '10 at 19:22
  • @Ivo: I actually do exactly that. But I don't want to, if it is not necessary ;) – NikiC Nov 24 '10 at 19:26
  • Well as others have pointed out, if one can sneak in something into your data IE is going to explode. – Ivo Wetzel Nov 24 '10 at 19:27
  • @Ivo: The people here all seem to think that I am completely stupid. If you have read my question, I would know, that I do know that there are security issues. My question is: How can someone (harmfully!) inject into my JSON string if it comes from my own server. Man-in-the-middle is not a real argument, because if you can MIM my JSON you can MIM my JS, too. – NikiC Nov 24 '10 at 19:48
  • @nikic Database injections would be one way, you should always try to get as **much** security as you can, of course you can drive without your security belt put on "Hey I know what I'm doing!" But does it make it any securer? (Well actually it might be even illegal in this case) – Ivo Wetzel Nov 24 '10 at 19:51
  • @Ivo: I don't know how SQLi affects my problem. As I already said: I encode the data using `json_encode`. That data might be fetched by SQL, but what does it matter? So the attacker might only change the contents of the transmitted object, not its syntax... – NikiC Nov 24 '10 at 19:56
  • 2
    @nikic That's still like saying "I don't need the belt, I got my airbag!" I could try to put a `function()` into a username, with some other specially crafted stuff in order to trick `eval` into parsing it, can't think of anything specific right now but if there's a will then there's a way. It all comes down to the question: What's the benefit of not using Crockfords JSON? I can't see any. If people are using an old Browser and it's slow, it there fault. If the get exploited because your system had a failure, it's your fault. – Ivo Wetzel Nov 24 '10 at 20:03
  • @Ivo: I don't get your logic. If somebody puts a `function()` in his username the browser would get `{"username":"function(){badBadStuff}"}`. PHP nicely put's it into a string literal - not harmful at all. Concerning your second point: Why should I use something, if I don't need it? – NikiC Nov 24 '10 at 20:09
  • @nikic "I don't need it" - What if others would say that too? "Oh we don't need native JSON or validation, we can just use eval, because we know that our server is secure!" - If everyone would say that... that would give me bad dreams ;) – Ivo Wetzel Nov 24 '10 at 20:20
  • @Ivo: I am a programmer, not a philosopher. So, can you tell me how somebody can make a syntax-breaking injection into my JSON using an SQL injection? If you don't know, simply say so. No need to answer with stuff like "I have bad dreams". – NikiC Nov 24 '10 at 20:25
  • @nikic From the top of my head I can't imagine something that breaks `json_encode` of PHP (that doesn't mean the whole thing is bug free) if you really want to leave out validation on your personal homepage, well then feel free to do so, but if there's even a chance that someone else might touch the PHP or the insert calls to the DB (or it's a bigger project), I'd make sure to have as much security as possible. – Ivo Wetzel Nov 24 '10 at 20:28
0

Tip: in asp.net using JSON is considered bad becuase parsing of DateTime differs between the server and the client so we use a special function to deserialize the date in javascript. I'm not sure if PHP has the same issue but its worth mentioning though.

Ali Tarhini
  • 5,278
  • 6
  • 41
  • 66
0

check out this:http://blog.mozilla.com/webdev/2009/02/12/native-json-in-firefox-31/

so at least for firefox you can use the built in json parser

Daniel
  • 2,331
  • 3
  • 26
  • 35
-2

Seriously? Some of the guys here are paranoid. If you're delivering the JSON and you know it's safe, it's ok to fallback(*) to eval(); instead of a js lib for IE. After all, IE users have much more to worry about.

And the man-in-the-middle argument is bullsh*t.

(*) the words fallback and safe are in bold because some people here didn't see them.

Camilo Martin
  • 37,236
  • 20
  • 111
  • 154