JSON : Naughty parsing is still allowed

Developers Kindergarten

Update 2020 Sep 01

Is this a “silly but harmless” or “crazy awesome dangerous” JSON handling, I would like to let you decide. Aeons after the original post, we still have these “JSON is not safe” issues in Chrome 85 and the rest. Few examples:

Chrome85 unsafe JSON parsing
Chrome85 unsafe JSON parsing

One can parse all sort of otherwise illegal JSON strings by using the good old  Function approach.  Ok, I admit. to fix this one I would not know, how. Anything I think of would provoke a lot of legacy code-breaking.

Update: 2010 Feb 01

I made a little “fuss” on the V8 (Chrome JavaScript engine) “Issues” forum, and today it appears to be fixed: http://code.google.com/p/v8/issues/detail?id=372 . So in “V8”, JSON.parse() , now works as it should. Therefore some near future CHROME update will not fall into “case 1” any more, in the code above.

Update: 2013 Jan 29

Of course, 3 years after the situation is much better in every major browser. But. These days we have a multitude of mobile device browsers which have to be tested. Not an easy task but there are teams doing it. This is nothing less than a good thing because this kind of code wakes me up in the early morning in a cold sweat:

Original Article 11 Jan 2010

JSON parsing? Well, that surely must be easy, is it not? Native JSON object is here, why should anyone now worry about Cross-browser JSON parsing, into the ES5 objects?

Base JSON syntax
Base JSON syntax

 

Yes, that line of thinking might be a sensible approach. But how is the issue of using “non standard” JSON strings solved in your “cross browser javascript” ?

Ok let us dive deep, without a hesitation.

IE8: JSON.parse("{ 'a':1 }") Syntax Error
CHROME JSON.parse("{ 'a':1 }") OK
FF JSON.parse("{ 'a':1 }") Syntax Error
OPERA 10.10 JSON.parse("{ 'a':1 }") Undefined variable JSON
SAFARI 4.0.4 JSON.parse("{ 'a':1 }") Syntax Error

See the problem? Your ES5 code receives JSON strings which are out of your control. And standard JSON string has to be embedded in single quotes and property names have to be in double quotes. Like so:

The problem is that not every browser follows this simple rule. While CHROME 4.x, which is/was a browser with (very) a significant number of users, does not. That is perhaps not such a big issue. The big issue is that today on the WWW there are a large number of legacy systems connected to it, all passing JSON “almost-standard” (aka “illegal”) strings around.

I suppose, now you might reply: “…OK, why support non-standard usage … ?”. And then someone else might reply: “but CHROME does”? Ad infinitum … Instead of endless debate, I suggest a slight detour.  Here is the trick: JSON.parse() does not have to be used to “parse” JSON strings. The good old Function() approach, “just works” :

Above “trick” works in each browser, regardless of the fact that string passed in, sometimes is not a proper JSON syntax. This works everywhere, including IE8, FF and SAFARI where JSON.parse("{'a':1}") dutifully throws an exception. Above trick also works in browsers which have no JSON as a native object at all. End of detour.

Good in case you want to support it. I don’t. Here is why.

By now perhaps you might want to adopt a more sensible approach? No compromise approach where your library will NOT allow for non-standard JSON strings, any more!

Maybe I did not say it clearly enough, so I will do it now: I agree 100% with a no-compromise approach to “almost-standard” (aka illegal) JSON strings. It is only that in reality, there are well known and (commercial) paid for RESTfull services, which return this wrong kind of JSON.

Especially this kind: ” { look-ma-no-quotes : 1 }” is, it seems, in widespread use. No quotes whatsoever around names.

What is also relevant in this context, is that there are other JSON issues, especially security ones. Issues much larger than travails of any JavaScript library out there. And they need to be ultimately re-solved by W3C, IEEE, http://www.soa-standards.org/, etc …, not jQuery, Dojo or any other “ninja” team. In my opinion, the best one can do, for her library, is to document these issues. And that will immediately show if the browser of choice is not capable of legal JSON parsing.

What is especially worrying is that new kind of “AJAX” (not AJAX) platforms are starting to appear. Non-dom and non ES5 code, which “just” uses the idea of  REST (JSON + HTTP). Like Node.js or Ruby apps or Python Tornado… all happily working without dom, JavaScript or browsers. And which talk to some external and proprietary server-side quaky “REST”, (not REST).

This issue is old news with XML, but XML text is not a source of any programming language. JSON is much more dangerous since it actually is source code, not a document markup language like XML is.

As a very good example. In CHROME 4.x  window.JSON.parse will happily parse "{ 'a' : 1 }" which is not standard. It will even parse "{ a : 1}", and yes it will also parse this :

In your organization, You might want to allow for this or not. It is up to you. I would not. Actually the simplest “way out” is to check in your JavaScript library which browser it is currently in. In the case of omnipresent jQuery, I would add a new jQuery.support member :

As far as I know “only” in CHROME, the above yields true (Tested up to CHROME 4.0.302.3):

Having this in place, one can go ahead and implement her JSON parsing logic. Here is my attempt :

Above is definitely “slow and safe” approach. Perhaps this is good enough, to represent safe cross-browser JSON parsing mechanism?

Is the whole Internet actually safe as we think it is?

–DBJ

Leave a Reply to "Cowboy" Ben Alman Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 thoughts on “JSON : Naughty parsing is still allowed”