5 ms·
Why does Google prepend while(1); to their JSON responses?
- deleted 9y ago[deleted]
- samfisher83 9y agoWhy don't browsers strip cookies when they are doing cross domain javascript fetches?
- vbezhenar 9y agoBecause that's the way internet works and breaking it means breaking a lot of websites. Web security wasn't thought carefully when web was built, it's just a bunch of dirty hacks around most obvious vulnerabilities.
- captainmuon 9y agoIt would be easy to make sending credentials opt-in in a new HTTP or HTML version. The way it's done now is backwards IMHO. Define httpsb:// do be like https:// https://, but any site may make ajax and similar requests to it (without credentials). Then make some kind of exception (like csrf protection), or use legacy https, in case you need to send cookies.
- 0x0 9y agoBut an attacker would simply use <script src="https://.." https://..", instead of <script src="httpsb://.." ?
- deleted 9y ago[deleted]
- MereInterest 9y agoOnly if that is supported by the site being attacked. If the site only accepts httpsb connections, then the attacker would not have a way in.
- hdhzy 9y agoIf the site accepts httpsb it can as well support the Origin header [0] and the problem is solved. [0]: https://wiki.mozilla.org/Security/Origin https://wiki.mozilla.org/Security/Origin
- kuschku 9y agoThe whole point is to allow any site to access any other site, just like plain TCP sockets, without stealing your cookies. If the site wants to access google.com with its own cookies, fine, why not?
- hdhzy 9y agoCould you elaborate on the "stealing your cookies" part? Cookies are sent only to the origin that set them and (except XSS attacks) are not revealed to anyone else. So who exactly is stealing them?
- kuschku 9y agoWell, currently, nothing. But currently, the web is completely broken. If you want web-applications to be powerful, and open, you also need to be able to have any web application to access any URL. Why should only mail.google.com be able to access my emails, and not also my-little-opensource-webmail.com ? To faciliate that, without also adding cookie stealing back in, you need to allow any website to open standard TCP sockets.
- homakov 9y agoI proposed a header instead of a protocol btw https://medium.com/@homakov/request-for-a-new-header-state-of-the-art-9a1935bbad72 https://medium.com/@homakov/request-for-a-new-header-state-o...
- hdhzy 9y agoSounds good but I suspect it will meet the same fate as XHTML 2: designed to be clean and perfect but in reality it would take to much effort to implement and maintain. From your professional experience you can probably tell people would rather have slightly insecure site that works and gives profits rather than broken one because SOTA started including some new feature you didn't know... People would rather enable these individual headers one by one and see their effect. In h2 headers are compressed so it's not a big deal (besides looking ugly).
- homakov 9y ago> SOTA started including some new feature you didn't know if you sign for 2 versions, changes in 3 would not brake you. and the point is MANY things right now could be safe to turn on for 99.99%, e.g. XFO. So, not much effort
- amelius 9y agoI guess this is what you get if you let an advertisement company define the web.
- Tloewald 9y agoI'd say it's because of advertising mostly, but a lot of similar tech (that is usually ad supported) like Disqus. It's interesting that today cross-domain sandboxing applies to almost everything except JavaScript. If I load an image cross domain and draw it into a canvas, the contents of that canvas are sandboxes, but I can cheerfully mix and match code across domains too. Seems like it would be a good thing to do but it would break a ton of stuff.
- samfisher83 9y agoHaving advertisers not tracking you seems like a benefit not a con.
- slig 9y agoA benefit for us; a con for those developing or sponsoring the browsers we use.
- Tloewald 9y agoI agree, but of the four major browsers, two are directly underwritten by advertising (Chrome and Mozilla) and Microsoft is moving that way. Only Apple has backed off advertising as a revenue source, so it basically comes down to Apple being willing to cause massive breakage (the way it did with Flash) in pursuit of a principle. The fact that they enabled ad blockers in mobile safari says they are at least sympathetic to the idea.
- rodorgas 9y agoDid you mean Mozilla is an ad driven company?
- kijin 9y agoA very large percentage of Mozilla's revenue comes from search engines (recently Yahoo, previously Google) who pay Mozilla to make themselves the default search engine on Firefox. If Firefox users saw no ads and were untrackable, Yahoo would have no reason to pay anymore. Of course Mozilla doesn't try to force everyone to stick to the defaults, so you're free to change the default search engine and install a bunch of ad-blocking, anti-tracking add-ons.
- amelius 9y agoCan I turn this off?
- kalleboo 9y agoIsn't that what Safari does with the "Allow from current website only" setting? It defaults to "Allow from websites I visit", which means that only embedded content from sites you've visited before get their cookies, not random new embeds)
- extrapickles 9y agoThere is a newish cookie flag called samesite to do exactly this. Chrome is the only browser to support it though.
- kylebebak 9y agoI read about this recently. It's hard to believe these cookies didn't exist until 2016. The biggest problem solved by cookies has always been sessions. samesite is sufficient for most sessions. It seems like samesite should have been the default from the beginning.
- LoSboccacc 9y agoBecause not all websites can federate their users
- niftich 9y agoLack of focus, despite many years of research, literature, and attempts; interference with problematic techniques that have become really popular when alternatives sucked, like JSONP before CORS was ready, and before C-S-P was even thought of; worry about touching parts of the platform that have essentially been unchanged since the beginning vs. those parts that are fairly new and have in turn evolved quicker. On subject of the new SameSite cookie, I wrote a post that summarized my views [1]; it doesn't make for good quoting, but I briefly recount the history of CSRF and how its mainstream knowledge came around 2006-2008, some 5 years after the first sources that mention mitigating against it -- but a 2008 academic paper on it credits "(...) Chris Shiflett and Jeremiah Grossman for tirelessly working to educate developers about CSRF attacks (...)" -- Shiflett being same person who first wrote about this in 2003, and Grossman the one who discovered this flaw in Gmail in 2006. [1] https://news.ycombinator.com/item?id=13691022 https://news.ycombinator.com/item?id=13691022
- blntechie 9y agoIt's not the same but aren't the httpOnly cookies kind of serve the same purpose? JS can't read these cookies at all?
- hdhzy 9y agoJS can't (that protects against stealing the token) but the server still receives it even when the request originates from foreign domain. That's the gist of CSRF [0]. [0]: https://en.wikipedia.org/wiki/Cross-site_request_forgery https://en.wikipedia.org/wiki/Cross-site_request_forgery
- ubernostrum 9y agoBecause then they end up with a bug in how they do it, and oops. When developing web applications, you must approach this from the perspective of "what is the oldest, least-secure, most bug-riddled pile of C++ and plugins someone could try to hit this with". If you want an example of why this has to be the approach, well... six years ago the Django security team got an email from the Rails security team. Turned out something we'd both done in our CSRF protection systems didn't actually work. Protecting against CSRF while allowing XMLHttpRequest (remember this is 2011!) is kind of tricky, and the standard approach was one adopted by a lot of JavaScript toolkits: they'd set a consistent custom header (X-Requested-With) on the request. And since browsers only allowed that to be done on requests which obeyed the same-origin sandbox, it was reliable: you knew if you saw that header, it was an XMLHttpRequest that a browser had vetted for same-origin safety (or that it was someone faking a request outside of a browser, but that's not a CSRF vector). And then it turned out that thanks to a bug in Flash plus the way browsers handled a certain obscure HTTP status code, you could actually set that header on a request to any domain. Oops, that's a complete CSRF bypass in Rails, Django and I don't even remember how many other things. That's how we learned that particular lesson about trusting browsers to do the right thing, and I don't see myself ever trusting browser security like that again.
- CaliforniaKarl 9y agoI haven't worked with JSON like that before. Do JSON parsers properly ignore the stuff Google puts in, or do you have to strip it out before parsing?
- RKearney 9y agoIn the very first stack overflow answer: > an AJAX request at mail.google.com > will have full access to the text content, > and can strip it away.
- zoren 9y agoThat is one weird array in Google's reply. Looks like it could have been an object instead, whereby JSON hijacking wouldn't be a problem.
- frik 9y agoFB prepends a "for(;;);" which is 1 char shorter than "while(1);", has been the case since 2012/13. Firebug v2 and ChromeTools know how to parse such JSON and ignore that first part. (IE11 and Firefox newer DevTools can't "handle" it aka show just a plain text string)
- Lxr 9y agoWhy does it have to be a loop, couldn't you make a reliable syntax error in less than 8 characters?
- CJefferson 9y agoThe risk there is some parsers might carry on past the syntax error and try to continue parsing. This is JavaScript after all.
- minitech 9y agoNo, that’s not a real risk.
- minitech 9y agoI’m not sure why this is downvoted. No JavaScript engine does that. “This is JavaScript after all” is ridiculous FUD.
- CJefferson 9y agoI was sure I had used browsers which did that, if I didn't then sorry, I must be hallucinating. I wouldn't call it FUD, I'm not suggesting don't use JavaScript, and we are already talking in this article about one crazy workaround because of the weirdness of modern jazz development! The "this is JavaScript after all" referred to JavaScript tending to continue after errors (which it does in some cases, like a bad callback, or a whole file which didn't parse).
- winteriscoming 9y agoEverytime I read about such constructs, it makes me realize, as a regular developer, how complex web application security is and how difficult it is to think about and cover your application against each and every such potential problem.
- hdhzy 9y agoNote that these protections are only needed because Google supports every imaginable browser version even outdated ones. You most certainly do not need to do the same. Array and object globals cannot be overridden now (since 2007) for literals [0] and for ambient authority problem with CORS just check the Origin header. [0]: https://johnresig.com/blog/re-securing-json/ https://johnresig.com/blog/re-securing-json/
- emmelaich 9y agoThat would a good note to add to that StackOverflow question.
- fixermark 9y ago> You most certainly do not need to do the same. ... except that those browsers are still out there, so it depends heavily on how much damage someone can do by abusing the data your server can emit whether you need to do the same.
- deleted 9y ago[deleted]
- sagethesagesage 9y agoIt's more that people who use those browsers are being protected. It's not that those browsers can poke security holes in the site, they're just vulnerable to losing their own data.
- amenghra 9y agoIf you are browsing the web with a 10 year old browser you are opening yourself up to a ton of security bugs. Whether json responses contain a while loop or not isn't going to make a difference. The reason Google and Facebook keep this kind of stuff around is because it's there and doesn't hurt to keep it. There's a slight chance it will provide some protection if a similar attack vector is discovered.
- westoque 9y agoI wondered the same thing years ago. I always thought that browsers would have implemented other security measures so that websites avoid doing this. Around 90 something percent of websites I visit don't implement that `for(;;)` or `while(1)` solution. So are we saying that they're vulnerable sites?
- deleted 9y ago[deleted]
- Lxr 9y agoThe root object has to be an array I believe.
- coldtea 9y ago>So are we saying that they're vulnerable sites? We are saying that they're vulnerable for THAT particular issue (the JSON hijacking), and that is only if they don't already have some other way of dealing with it.
- raulk 9y ago> So are we saying that they're vulnerable sites? Not necessarily, if all their API responses are top-level JSON objects.
- minitech 9y agoNo, they’re not vulnerable; browsers fixed this bug a long time ago.
- xg15 9y agoI had a hunch that this is to prevent people from including the resource in a script tag - but I always wondered how they'd access the data as a JSON expression on its own should technically be a no-op when interpreted as JS (or so I thought). The overridden array constructor was the missing link. Though couldn't you have it easier by making sure your top-level JSON structure is always an object? As far as I know, while a standalone array expression []; is a valid JS statement, a standalone object expression {}; is not and would produce a syntax error.
- Lxr 9y ago.NET does this by wrapping things with {'d': data}, I always thought this was the reason.
- eriknstr 9y agoSomeone had the same question as you in a comment. >Wouldn't returning an object containing the array, instead of the array directly, also solve the problem? And someone else replied >No, that wouldn't solve the problem since the same attacks mentioned in the post could still be performed. Overriding the accessor methods to retrieve the info.
- wtetzner 9y agoExcept I don't think a JSON object is valid Javascript by itself.
- aetherson 9y agoWhat about a JSON object do you think is invalid Javascript?
- deathanatos 9y agoWhile the person you're responding to might genuinely be confused about JSON usually being valid JavaScript, arbitrary JSON isn't guaranteed to be: http://timelessrepo.com/json-isnt-a-javascript-subset http://timelessrepo.com/json-isnt-a-javascript-subset
- c0achmcguirk 9y agoI believe this hack (JSON Hijacking) was discovered by Jeremiah Grossman in 2005[1]. It's fascinating to read how he discovered it and how quickly Google responded. [1] - http://blog.jeremiahgrossman.com/2006/01/advanced-web-attack-techniques-using.html http://blog.jeremiahgrossman.com/2006/01/advanced-web-attack...
- NewEntryHN 9y agoGoogle use cookies to authenticate API requests?
- deleted 9y ago[deleted]
- stanleydrew 9y agoNot sure if they do, but why not? It's just an opaque token in the HTTP request content, same as any other opaque token.
- Animats 9y agoWhy not "while(0)"? Then an eval wouldn't do anything.
- orf 9y agoBecause it's not about eval(), as the link you're commenting on explains in detail?
- adrianmalacoda 9y agoIf I'm understanding it correctly, though, prepending while(0) or even if(0) to the JSON would prevent the attack, because the JSON object would not actually be executed. I think they were asking if there was any particular reason to prefer the infinite loop over that. The answer that comes to mind for me is that having the script hang is a more obvious failure state than simply skipping over the statement, and makes it more immediate that something has gone wrong.
- deleted 9y ago[deleted]
- tossaway322 9y agoJeez, why not live w/o JavaScript? We keep trying to accomodate a defunct language with insoluble problems. Isn't that an error in our thinking processes? https://www.wired.com/2015/11/i-turned-off-javascript-for-a-whole-week-and-it-was-glorious/ https://www.wired.com/2015/11/i-turned-off-javascript-for-a-...
- _pmf_ 9y agoNot only that. They keep piling on new shit APIs. Half of the WebGL exploits are probably yet unveiled, there's a side channel attack using the new ambient light sensor API, but hey, my phone can get darker based on ambient light, hooray!
- the_mitsuhiko 9y agoPretty sure browsers no longer permit overriding ctors for literals.
- gavinpc 9y agoThe John Resig post linked by TFA indicates that this was originally dealt with by locking the constructor altogether: function Array(){ alert("hello, I found something of yours!"); } // ERROR: redeclaration of const Array But it appears that the restriction now applies only to literals, as I can do this in at least Chrome and Firefox: function Array() {console.log("hope")} undefined var x = new Array(3); hope undefined https://johnresig.com/blog/re-securing-json/ https://johnresig.com/blog/re-securing-json/
- maambmb 9y agoI feel like the browser could use the Content-Type header to check whether the response is JSON or actual executable javascript - throwing an error if the former