So Rob and others have both pointed out that I used the term JSON incorrectly when referring to approaches 2 & 3 in my "Safe JSON" post. They are, of course, completely correct those approaches are returning Javascript and not JSON.
That got me thinking though is JSON Javascript? JSON is absolutely a valid javascript "expression", but does a piece of JSON represent a complete Javascript "program" as defined in the Emcascript standard Chapter 14 (page 75), i.e. should JSON be executable? As far as I can make out from reading the spec, JSON is a valid Javascript program and the implications of this fact seem to render JSON pretty much useless as a data exchange format for any kind of private data.
Joe has already demonstrated that it is possible to get at data in a JSON array using a CSRF attack and went on to show that you could also do it for JSON objects. These attacks work as the JSON executes as a Javascript "program" when included by a <script> tag. However, he is kinda cheating. To get the object hack to work he had to surround the JSON with () as mentioned in the comments. So strictly speaking his attack doesn’t work on pure JSON objects on Firefox at the moment. When you try it with a pure JSON object you get a parse exception as I pointed out to Joe.
But here’s the question should it work?, and this brings us back to whether JSON is a valid Javascript program. If it is, and from reading the spec I think it is *blush* it isn’t, then firefox should really fix the bug that is incorrectly parsing a JSON object when included as a piece of Javascript via a <script> tag and Joe would no longer need to place the JSON object in () to get the object attack to work.
It appears that a data interchange format has been "conflated" with an executable program and as such we have a huge gaping hole in the security of using JSON as a data exchange format.
I hope I am wrong about this, but it was interesting to discover that the guy that wrote the JSON RFC has tried to tighten the javascript standard and in his verifier JSON is NOT a valid javascript program. Maybe he knows something the rest of us are just figuring out.
As an aside connections will NOT be offering a JSON api.
Update So Lenny’s comment had me take a second more detailed look at the ECMAScript spec and it appears that JSON Object Literals are safe, more out of luck than by design. JSON Object literals are valid "Expression" Chapter 11 p40 and so I incorrectly inferred that they were "Expression Statements" Chapter 12.4 p63 . However the spec clearly states "Note that an ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block." and so parsers should infer that the contents of the JSON Object Literal to be a block and as the contents of JSON Object Literals are not valid Blocks it should error out.
Lenny summarizes it well.
"As I see it, the takeaway from all this is that the root of any private JSON document should be an Object, never an Array <snip/> Prescription: don’t start your JSON doc with [, and don’t deviate from the spec with things like parentheses."