Live data from Hacker News

JSON users: Avoid CSRFs by not using top-level arrays

flask.pocoo.org

11–20 of 85 posts

Re: JSON users: Avoid CSRFs by not using top-level arrays

#12
post #5

Earlier quoted context omitted.

I 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 sid…

You 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…

This is good advice, but a non-sequitur in this case. This is not a code-injection attack, this is an information leak. It lets an attacker get around the normal constraints on fetching cross-site URLs. There is an EVAL happening, but it's being done by the attacker, not by you. And it's being done implicitly. The real problem here is a security hole in Javascript itself. It's too flexible for its own good.

Re: JSON users: Avoid CSRFs by not using top-level arrays

#13
post #5

Earlier quoted context omitted.

I 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 sid…

You 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…

I agree that eval() is evil and JSON.parse() is the way to go.

However, in this particular case this doesn't matter much, because the site itself controls where to load the JSON from. Manipulating the JSON response requires access to the webserver or the DNS, and in those cases the attacker could have manipulated the initial HTML response as well.

> 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.

This totally misses the context of the article. The article is about CSRF. That is, the _attacker_ downloads and executes the JSON.

This is _not_ about downloading the attacker's JSON! It is about how to construct the JSON in a way that it is unaccessible through a tag from the attacker's site.

Re: JSON users: Avoid CSRFs by not using top-level arrays

#14
Generally speaking, all incoming requests should be verified - authorized or not. These days with all kinds of wonderful web frameworks, CSRF protection is pretty simple. Django handles CSRF with a token in a hidden form field: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Re: JSON users: Avoid CSRFs by not using top-level arrays

#15
post #10

Earlier quoted context omitted.

You 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…

[deleted]

Patience. Writing a good response takes a bit longer than downvoting.

Re: JSON users: Avoid CSRFs by not using top-level arrays

#16
post #3
post #2

Facebook is dealing with this by prefixing some of their JSON responses with "for(;;);".

Sometimes the laziest solutions are the most elegant.

Tangential: 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

Re: JSON users: Avoid CSRFs by not using top-level arrays

#17
post #5

Earlier quoted context omitted.

OK, 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?

I 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 sid…

This will stop embedding it in but why couldn't the attacking website do the same with eval and substring?

Re: JSON users: Avoid CSRFs by not using top-level arrays

#18
post #5

Earlier quoted context omitted.

I 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 sid…

This will stop embedding it in but why couldn't the attacking website do the same with eval and substring?

Because you cannot issue cross-domain AJAX calls, the attacker does not have access to the response body as a string that can be manipulated.

https://secure.wikimedia.org/wikipedia/en/wiki/Same_origin_p...

Re: JSON users: Avoid CSRFs by not using top-level arrays

#19
post #14

Generally speaking, all incoming requests should be verified - authorized or not. These days with all kinds of wonderful web frameworks, CSRF protection is pretty simple. Django handles CSRF with a token in a hidden form field: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

This does not help at all in this case, proving that it is not that simple.

Re: JSON users: Avoid CSRFs by not using top-level arrays

#20
post #14

Generally speaking, all incoming requests should be verified - authorized or not. These days with all kinds of wonderful web frameworks, CSRF protection is pretty simple. Django handles CSRF with a token in a hidden form field: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Having a CSRF token on your forms does not prevent, and has nothing to do with, with the attack in the article.
Post reply on HN