3 ms·
Facebook is dealing with this by prefixing some of their JSON responses with "for(;;);".
by bemmu 15y ago
Facebook is dealing with this by prefixing some of their JSON responses with "for(;;);".
- jarin 15y agoSometimes the laziest solutions are the most elegant.
- telemachos 15y agoTangential: One of my favorite pieces about simplicity, laziness, dogmatism and getting things done is from Mark Jason Dominus[1]. His context isn't connected to this at all (it's about when and whether to use shell commands inside Perl scripts), but the larger point is very relevant: taking "Do the simplest thing that could possibly work" seriously can have surprising outcomes. tl;dr Sometimes ugly is elegant, too. [1] http://perl.plover.com/yak/12views/samples/notes.html#sl-3 http://perl.plover.com/yak/12views/samples/notes.html#sl-3
- AndyNemmity 15y agoInteresting article, and I had a similar issue with #perl recently as well. They started with trying to fix a performance problem I didn't have, and then after my refusal to give them more information to fix a problem I didn't have, started insulting me.
- gambler 15y agoThey are adding executable code at the beginning of what is supposed to be a data structure. This solution is not elegant at all. It's an ugly hack that uses a side-effect of code to plug a hole in a rather convoluted security model. Edit: Come to think of it, this seems to be solvable by a much better method - the same one that is used to prevent standard CSRF. The problem is effectively the same. Server A is a valid server. User logs into it and gains privileges. Then he visits server B, which is a bad server. B tricks the browser into sending a request to server A to do something (abusing the elevated privileges). The only addition with AJAX is that server B also manages to read the result of its attack. That wouldn't matter if it couldn't trick the server A honoring that page request in the first place. You can easily solve this by signing your requests, effectively binding two pages on your server together. Normally, PAGE1 has a form (or JS code) that requests PAGE2. You simply need to enforce that only legal (yours) pages can do that. This is achieved by adding a token to PAGE1 that must be sent to PAGE2. For example, token = hash(server_secret + PAGE2_identifier + user_id). Upon receiving a request for PAGE2, the server will know all the arguments that went into creating that token, and re-generated. If the user-supplied token and server-generated tokens don't match, the request is denied. As long as client side scripts from server B cannot read the token from server A, this should work even with AJAX requests. Since attacker (server B) cannot know server_secret, they will not be able to guess your generated token, and their requests to PAGE2 on server A will fail.
- timmorgan 15y agoOK, I see how that prevents an attack (it seems to create an endless loop), but how does this parse as regular JSON for the good guys?
- sonnym 15y agoI imagine they simply remove the first 8 characters from the response string. eval("(for(;;);{})"); doesn't work, but eval("(" + "for(;;);{}".substring(8, 10) + ")"); works fine where 10 is the length of the response string. EDIT: This is the correct idea. Search for shieldlen or safeResponse in the JS to see how it is implemented. There is always something interesting to be learned by digging through FB's client side code.
- JonnieCache 15y agoYou should never be eval()ing json, thats the most dangerous thing you can do with it. All browsers have had native JSON parsers for years, which will choke on any code that's sent through them. These will be automatically employed by any js framework you're using, or I think its generally JSON.parse(). By eval()ing your json you are doing most of the attackers work for them. All that stuff in the article about mime types is redundant if you're eval()ing your json. Basically, don't ever eval() anything, in any language.
- sonnym 15y agoWhile I generally agree with your sentiment, I was merely writing a brief proof of concept test in the firebug console. From: http://www.json.org/js.html http://www.json.org/js.html "The use of eval is indicated when the source is trusted and competent. It is much safer to use a JSON parser." FB is still using eval() if you look at their code. As the source of the JSON is their own service, and they can, therefore, trust it assuming proper sanitization; the same applies for my test case.
- deleted 15y ago[deleted]
- benjoffe 15y agoYes and Google has 'throw 1;' at the start of some of their files IIRC (may be some other value than '1').