14

I get that JSON.parse() prevents an attacker from injecting javascript into the response since a JSON parser is just a text parser, not a script parser so please don't close this is a dup of all the other questions that talk about that. This is a different question.

If an attacker can hijaack your Ajax call and put javascript into the Ajax call aren't they just as likely to be able to hijack your actual webpage and put arbitrary javascript into your page from which they could accomplish the exact same attack?

Sure, you have nothing to lose by using JSON.parse() instead of eval() (unless you don't have a JSON parser yet in your environment and have to add more code to get one), but what situations does it really add safety if your web page is being served by the same host as your ajax call?

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 3
    I wonder if this belongs on the [IT Security StackExchange](http://security.stackexchange.com)? – 700 Software Jul 20 '11 at 16:23
  • 3
    I put it here because this is where everyone who posts a piece of code that uses eval() gets hammered about how unsafe it is. – jfriend00 Jul 20 '11 at 16:30

4 Answers4

14

Yes, it is really safer. Every precaution you do not take is a set of potential exploits you don't prevent.

An attacker might be able to have some control over your server's output without being able to change it entirely. Nobody's suggesting it's a magic bullet, but it's potentially faster and you're not creating a potential vulnerability that could come back and hurt you.

Maybe someone running your server is having a bad day, and does something silly like constructing JSON by concatenating unsanitized user input:

<?php
    print '{"foo": ' . $_GET['bar'] . '}';
?>

If you're using JSON.parse, the worst they can do is shove a large object into your memory. If you're using eval they can hijack everything.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • +1 for providing an example of how `JSON.parse` is indeed more secure given the OP's original specs. – 700 Software Jul 20 '11 at 16:58
  • OK, the one example we have so far is that a bonehead administrator messes up your ajax response in a way that's somehow valid Javascript and dangerous. – jfriend00 Jul 20 '11 at 18:05
  • Why is JSON.parse() faster than eval()? Are you saying that parsing the JSON in Javascript is faster than the interpreter engine behind eval()? – jfriend00 Jul 20 '11 at 18:06
  • @jfriend00 In newer browsers, yes. They have to parse a simpler language and don't have to execute the result, it can be much faster. – Jeremy Jul 20 '11 at 18:09
  • 1
    @jfriend00 It's a slightly contrived example, but it seems like most of the times sites are hacked it involves stupidity like this; it's not entirely unrealistic. You seem bothered by people over-emphasizing this point. I'll concede that it's not the largest issue in the world, but it helps in some cases and there's no reason not to do it. – Jeremy Jul 20 '11 at 18:11
  • 1
    It's just that it's sacrilege here on SO to ever use eval and the level of emphasis seems way out of proportion with what it helps with. If you're worried about hacks, it seems way more important to use https to defend against man-in-the-middle attacks that would add some protection to injection into your core web page, yet that is hardly ever mentioned. I'm not arguing against JSON.parse(), just that it seems emphasized more than security precautions that would have way more benefit. – jfriend00 Jul 20 '11 at 18:17
  • @Jeremy. Ahhh, if you mean a native implementation of JSON.parse(), I can buy how that might be faster (though that isn't prevalent enough to rely on yet). I was having a hard time understanding how an implementation written in Javascript would be faster. – jfriend00 Jul 20 '11 at 18:19
  • @jfriend Yes, that's all I meant. The newest versions of all major browsers support native `JSON.parse`, so I think it's always worth checking for. – Jeremy Jul 20 '11 at 18:21
  • 1
    @jfriend00 I agree with Jeremy's 2nd comment. Although this is a contrived example, it is not unrealistic. There are many ways to inject content through a webapp. I use if statements to call JSON.parse when available. – 700 Software Jul 20 '11 at 18:51
  • 1
    @jfriend00 Also, I understand your frustration. [I asked a question](http://stackoverflow.com/questions/4880535/is-it-safe-to-copy-a-reference-to-a-native-javascript-method) and in less than 2 hours there were 15 comments with an argument about semicolons, and more the next day. (those who run across, please do not continue commenting) I can't think up how to reduce these types of so called "holy wars" except maybe a blog post from Jeff Atwood or Jon Skeet that we can point people to. Now I just ignore those types of arguments unless I can carefully put an end to them. – 700 Software Jul 20 '11 at 18:53
2

Well, if they're able to inject into your AJAX responses they've probably already successfully man-in-the-middle'd you in one way or another (ARP, DNS or something else).

See http://en.wikipedia.org/wiki/Man-in-the-middle_attack for more details on these types of attack.

You are correct in that, if they can inject into your AJAX response, they can inject whole pages as well. Really, anything you receive OR send via networking is now vulnerable in a MitM unless something like HTTPS\SSL is being used.

mikeycgto
  • 3,368
  • 3
  • 36
  • 47
1

That is a very good point. The only thing I can think of is that JSON.parse would have opportunity to be faster than eval.

A much less likely advantage is if the browser already has the HTML/JavaScript cached and the server uses Cache-Control to say that it does not need to reload. If that happens then of course a person intercepting would not have a chance to modify the page. But that is a very rare set of circumstances. Chances are, you are going to require the browser to check for a newer version of the HTML/JavaScript which is the default behavior.

As for the security difference, I think you are correct.

As for myself, I work with HTTPS confirmed systems only. But I have a function that uses JSON.parse if available and falls back on eval just for the speed improvement.

700 Software
  • 85,281
  • 83
  • 234
  • 341
-1

Well... I'm not advocating the usage of eval, but I don't think it constitutes a security issue in Javascript, because Javascript is client-side language. If you don't use eval in your code, what prevents me from running javascript:my_own_evil_code() in console or address bar? It is Javascript, I can run my own code or modify yours, create my own HTTP requests and do anything with HTTP responses, or even add my own eval to your functions.

You shouldn't use eval if there is another comparable solution available, but if you, just for simplicity, want to do eval('('+jsonstring+')') to emulate JSON.parse, I don't think it is a big mistake.

duri
  • 14,991
  • 3
  • 44
  • 49
  • 2
    This isn't about the user running code in their own page. This is about an external attacker injecting code into your page. So ... the address bar example isn't really what this is about. There are all sorts of tools (like GreaseMonkey) who's sole purpose it to help you run extra code in your own pages. The user is allowed to do that. – jfriend00 Jul 20 '11 at 18:03
  • 3
    @jfriend00 Please, be more specific. If an attacker is able to inject some code, it's already a huge security hole, no matter if there is `eval` in the source or not. For example, if an attacker can modify the response of HTTP request created by `XMLHttpRequest`, he can also modify the main file (w/Javascript) and thus run his own code. I'm almost sure that if you show me any case of using `eval` to run attacker's code, I'll also show you how to do it without `eval`. – duri Jul 20 '11 at 19:03
  • 2
    That's my point too. Since most attacks that would be able to modify an ajax response could have just modified the host page in the first place (directly injecting their own JS into it), protecting the ajax response isn't buying you much. Putting a double lock on one door when all the other doors only have single locks doesn't buy you much additional protection, particularly when the windows aren't very secure. – jfriend00 Jul 20 '11 at 19:13