----
I would be wary of solving the problem this way.
The problem is the object/array combo you're talking about is still perfectly valid JavaScript. However, due to the way browsers handle JavaScript, it's not currently possible to access the data from it. If you do implement it, you run the risk of a browser changing its behavior ever so slightly and destroying your security. ;-)
The way I've typically seen this done is to add a prefix of some kind to the data. The prefix can be valid JavaScript (eg: while(1); or throw 1;) or it can be text that JavaScript can't parse. Either way, the point is to ensure that a cross-domain request via the <script> tag will fail and not be able to get to the data. These solutions are slightly better because it's less likely that these constructs will become valid in the future (although still possible).
With that being said, here's the advice from the Browser Security Handbook, which advocates for a slightly different solution (http://code.google.com/p/browsersec/wiki/Part2):
Note: quite a few JSON interfaces not intended for cross-domain consumption rely on a somewhat fragile defense: the assumption that certain very specific object serializations ({ param: "value"}) or meaningless prefixes (&&&START&&&) will not parse via <SCRIPT SRC="..."> or that endless loop prefixes such as while (1) will prevent interception of the remainder of the data. In most cases, these assumptions are not likely to be future-safe; a better option is to require custom XMLHttpRequest headers, or employ a parser-breaking prefix that is unlikely to ever work as long as the basic structure of JavaScript is maintained. One such example is the string of )]}', followed by a newline.
http://directwebremoting.org/blog/joe/2007/03/06/json_is_not...
Doing a `while(1);` would be much more robust.
If you only return data to XHRs then you're protected by same origin policy and all <script> tags will get no data.
-EDIT-
When I first read "a better option is to require custom XMLHttpRequest headers" I thought this is what they were talking about. After a second look they probly mean setting a custom header yourself using the XHR object. This would work too but now I'm wondering if there's some way around my solution. Because why would they advocate a custom header if checking the X-Request-With header alone is enough?
- EDIT -
Was just in the shower and remembered why they probly don't advise to just check the X-Requested-With header. There are ways for an attacker to get around the XHR same origin policy with dns pinning/rebinding attacks. If you required a custom header with a session cookie which the attacker didn't have access to this would mitigate that kind of attack. EDIT: Nevermind, as long as you're checking the Host header a dns rebinding attack wouldn't matter.