Why does Google prepend while(1); to their JSON responses? (2010)
stackoverflow.com
stackoverflow.com
What an absolutely ridiculous language and platform we decided to base the whole web on.
JavaScript is used for its virtues, and its flaws can be mitigated.
Other languages might not have those flaws, but they have other downsides.
It's not like English is the best choice for language either!
It's not that different from English, in a sense.
Pages could have more control (via a header manifest or something) over tracking and permissioning based on where particular scripts come from; but that's not the model we went with. All scripts get put into a single executor and namespace. Now, this isn't an irrevocable choice, but a browser still has to support existing pages that would still be vulnerable to fun XSS attacks.
On a similar note, it's also crazy that you can't just use `foo instanceof Array` to figure out if something is an Array because it could be an Array from a different namespace, instead you need `Array.isArray(foo)`.
For example, look at the following code:
function test(a) {
if (a > 1) {
console.log("bigger");
return;
} else if (a <= 1) {
console.log("smaller");
return;
} else {
console.log("Why is this happening to me?!");
}
}
var a = { x : 1,
valueOf: function() {
this.x -= 1;
return this.x==0?1:2;
}
}
test(a); * objects created in the same scope
* objects created outside the current scope but global
* global objects
* core language features
For anyone who has to read code someone else wrote, as you go down this list life becomes much more painful. Even something as simple as forcing all the patches to be in one place so there is an unambiguous place to look for them would make a huge difference.In python you can certainly define your own object which might be a list and override the list accessor for your object, but you cannot override the general list accessor for all lists or those lists that you don't have a reference to.
This is a big difference between a language like python and javascript.
In javascript, buried deep in a function scope of some library might be code that overrides Function.prototype.apply, and then everywhere else in your code that a function is invoked, the new behavior will take effect. Nothing like that type of interference is possible in Python. In Python, you can only monkey patch those things that you have a reference for.
class A(object):
def foo(self):
return 'foo'
a = A()
a.foo() # returns 'foo'
a.__class__.foo = lambda self: 'bar'
A().foo() # new instance (!) returns 'bar'
You're correct for list ("TypeError: can't set attributes of built-in/extension type 'list'"), but that's more a implementation limitation than a principled stance.But what you can't do in Python is monkey patch a method to a class for which you don't have a reference. Try it.
This is not an "implementation limitation", it is because Python is not a prototype language, so you can't monkey patch what it means to "call a function" for every method in every class because there is no "Function" object that is a prototype of all method calls in Python that plays a similar role to Function in Javascript. Similarly you can't patch "Object" de-reference and change the behavior of every single object de-reference. Those prototype chains are not exposed to you.
In javascript you can override methods of classes which you can't reference. That's huge. Imagine one person creates an object with a foo method, and someone else changes what it means for all objects of any class to call any method. Think about what you have to audit to determine what the behavior of foo is -- in Python, you just need to audit anything that has a reference to the class where foo is defined. In javascript, you need to know what all the code is doing. That's a big difference.
Yes, gevent did have a reference to the classes it was patching, but it still made pretty deep changes to a program.
It was janky and has been replaced several times by other async frameworks. It doesn't go as far as javascript to be sure, but it is sort of what you're suggesting.
That, combined with the fact that people load thousands of modules just to do simple short programs, makes it very hard to reason about javascript code efficiently.
You can try to hide global references from a javascript module, for example by using "with", but you will always have access to things like constructor() which will give you the raw window, so you can't hide a reference to Window even if you shadow Window via "with".
Even ignoring that, you still can overwrite builtins from anywhere in the code, thus effectively changing the shared runtime. There is no notion of scoped builtins -- e.g. overwrite builtins all you want, but just in your own scope.
That lack of isolation is the problem, not monkey patching your own objects.
Originally at https://code.eligrey.com/sec/json-hijacking (archive: https://web.archive.org/web/20100304213300/http://code.eligr...)
Mentions how inconsistent usage of the XSSI prevention caused a information leak that could detect which user was logged into Facebook - received a bug bounty of $1000 from Facebook.
Previous discussion: https://news.ycombinator.com/item?id=19306309
Usually i check.
Very meta.
See also https://stackoverflow.com/questions/15306636/why-do-facebook...
HN discussion: https://news.ycombinator.com/item?id=18443125
---
While this vulnerability is getting old, it's very interesting to see its prevention still in effect on major websites. Even if the original vulnerability is patched, we never know when a modern variant might pop out, such as using UTF16BE as charset to extract array data!
while (a++ = b++);
while (*a++ = *b++);There are too many conflicts on interest to fix the broken client.
https://portswigger.net/blog/json-hijacking-for-the-modern-w...