Why does Google prepend while(1); to their JSON responses?
stackoverflow.com
stackoverflow.com
It's fascinating to read how he discovered it and how quickly Google responded.
[1] - http://blog.jeremiahgrossman.com/2006/01/advanced-web-attack...
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.
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.
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.
Define httpsb:// do be like 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.
If the site wants to access google.com with its own cookies, fine, why not?
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?
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.
https://medium.com/@homakov/request-for-a-new-header-state-o...
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).
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
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.
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.
[0]: https://en.wikipedia.org/wiki/Cross-site_request_forgery
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.
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?
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.
Not necessarily, if all their API responses are top-level JSON objects.
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.
>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.
> eval('{"key": "value"}');
SyntaxError: missing ; before statement
You can get around this by using parens: > eval('({"key": "value"})');
Object { key: "value" }
But accidentally including a JSON URL in a script tag should fail to evaluate if there's an object at the top level.As script blocks expect one or more statements to execute, the hack relies on the fact that some JSON (array literals) also happen to be valid statements in addition to expressions.
Yes, this works too. You’re correct about any keys causing a syntax error.
> an AJAX request at mail.google.com
> will have full access to the text content,
> and can strip it away. 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/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.
... 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.
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.
[0]: http://webassembly.org/docs/faq/#is-webassembly-trying-to-re...
First of all browsers are committed to backwards compatibility.
Secondly, there's huge amounts of Javascript written right now, nobody's going to throw away billions of dollars worth of investments. People complain about Cobol written in the 60's, when the programmers counted in the thousands. Javacript today is written by millions of programmers.
And thirdly, Javascript evolves, as do browsers.
It's not very hard to imagine, especially in an enteprise environment, running a browser 15-20 years from now and that browser loading the equivalent of the JVM, .NET CLR, Ruby VM, etc., on top of WASM :)
AFAIK it never went anywhere, but maybe building an entirely new OS/Browser based around WebIDL seemed less insane 10 years ago.
Yes, I'm being somewhat hyperbolic. Bring on the downvotes! ;-)
All sufficiently complex ecosystems are a giant, flawed mess.
This is not a bad thing, for the simple reason that every long-lived complex system involving many humans must behave this way.
Any attempt to top-down design the perfect, universal, distributed application runtime hits fundamental social problems not unlike those in a centrally planned economy: too much information to integrate, too many stubbornly uncooperative humans with their own divergent goals and opinions.
Systems at this scale are much more like biology than like circuit design.
The idea that systems are fixed entities that have to be designed correctly up-front is wrong and is one of the reasons why the Waterfall model of software development has been superseded by Agile.
Good systems have to be designed to handle change. Change is the only constant thing in this world.
Security takes a back seat to reproductive fitness of the web as a platform. JS made the web insecure, but it also made it the world's premier application platform.
I blogged about this: http://kylebebak.github.io/post/browser-security-worse-is-be...
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)
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).
Autocorrect of “JS”? If so: it’s not a modern weirdness; this is an old, long-fixed browser bug.
FWIW, JavaScript continues executing after errors in cases where it makes sense. If an event listener throws an error, it doesn’t make much sense for it to stop all future events without crashing the page (which is kind of what IE used to do with its script error message box, and we know how that turned out).
But getting hit with this, they would be actively hurt, and I don't think that interpreter session would be able to recover.
If your responses are all between 505 and 512 in length then it might matter but most likely you are prematurely optimizing.
https://fonts.google.com/metadata/fonts
And here's the code in Angular's $http service for stripping out that string:
https://github.com/angular/angular.js/blob/master/src/ng/htt...
I believe that some browsers used to do that some times ago.
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.
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-...