I think it's important to note that this is a bug that effects older browsers only. Modern IE, Chrome, and Firefox have security measures that do not allow scripts to capture values passed to constructors of a literal. That way, this hack is only needed for older browsers and will hopefully not be needed at all in the future. For more info: http://stackoverflow.com/a/16880162/372767
Also note that this attack, JSON Hijacking, is different than a CSRF (Cross Site Request Forgery) and has little to do with CSRF tokens.
> Modern [browsers] have security measures that do not allow scripts to capture values passed to constructors of a literal.
Actually, it's not security measures so much as implementing ECMAScript 5, which explicitly says that array literals must use the built-in constructor, not any override. See 11.1.4 [1], which reads:
> Let array be the result of creating a new object as if by the expression new Array() where Array is the standard built-in constructor with that name.
Object works similarly, and is in 11.1.5. I'm not certain what earlier standards said here, but I suspect they didn't say anything.
Actually, ie is still vulnerable to a very similar attack in some cases, specifically you can leak responses containing small json array by inlining the json as a script[src=vbscript] tag. Disclosed here: http://en.wooyun.org/bugs/wooyun-2013-023
with the status "unable to contact the vendor or actively neglected by the vendor" :-/
Edit: I meant "injecting" not inlining. Thanks chc for pointing that out.
If it has to be inlined, how is that the same vulnerability? I thought the vulnerability was that script tags can fetch external scripts and a local script intercept the results. If you have to inline both scripts, you can only attack yourself.
Wow, I was just having this discussion on an issue for a CSRF protection gem[0]. From what I can tell, IE wasn't even susceptible to this (perhaps accidentally) as far back as 6, and it's been fixed in Firefox since 3.1, and Chrome around the same time. I've been wanting to run a test case against a bunch of browsers to prove it to myself, but this seems to be a complete non-issue nowadays.
Well, one thing to do with the tokens might be that if the token were required for the GET request in question, then stealing the content via script tag may be harder. OTOH, putting one-time tokens on every request might be a bit too much for many apps, while(1) hack may be more efficient.
Chrome DevTools recognice while(1) and for(;;) in the network tab (JSON preview). Sadly, Firebug still doesn't know how to handle this and shows no JSON preview :(
No current browser should be vulnerable to this (ES5 requires object literals use [[DefineOwnProperty]], not [[Put]], and hence no setter on the prototype chain should be called). I believe all browsers have since fixed this.
After seeing this I went to see if AngularJS had anything built in to mitigate JSON hijacking and they do. It will strip ")]}',\n" off of json responses if included from the server.
Because the script is useless, malicious websites won't bother including it, so the folks at Google don't really care what it actually does. Or, if the site wants to be malicious by just giving you a while(1), they can do that without Google's help.
I recall IE showed a dialog on javascript errors to ask if the user wanted to continue. An infinite loop will get the entire script aborted because there's no obvious way to continue.
When you have n-hundred-million people's personal information at stake, 'currently non-existing (but multiple-times previously existing)' is not very reassuring. There's nothing wrong with multiple layers of safeguards.
I imagine it assumes a header like X-Requested-By has not been manipulated. You can safely assume that the referrer, or other headers, have not been manipulated. There is no way for malicious Javascript running in the users browser to edit headers.
Of course, anyone can code their own browser to lie about headers. It doesn't make much sense to specifically open yourself to vulnerabilities though.
Hey Egor, article author here. How come you are not such a fan of checking referer? It cannot be a global fix (some sites depend on serving xdomain scripts, have lots of users with proxies that alter headers etc), but it should work well for many cases no?
This is specifically dealing with reading results from a remote script- with a CSRF you often (usually? Always?) don't care about the result, because the damage has been do e by the time you are successfully able to send an authenticated request.
Also note that this attack, JSON Hijacking, is different than a CSRF (Cross Site Request Forgery) and has little to do with CSRF tokens.