Tuesday, April 24, 2012

CSRF afterparty & MUST READ rules

Good day everyone! HN submission

A month ago I was possessed with CSRF and related stuff. I received quite useful and interesting feedback on initial "Theory" post. In a nutshell it was a *traditional* negation "not our problem, it always has been working this way, apps should protect themselves". Now, let me to give up my proposal(introducing "top bars" for allowing/disallowing POST request in every browser by default) because it is too radical and backwards-incompatible. You win. I'm always open to discuss solutions/attitudes and this time I really changed my mind and want to be "agile" with real world facts and your opinions!

But you should do the same. Also I wrote a post demonstrating a few CSRF vulns on popular/alexa top websites. It was marked [dead] on HN though - I don't know why :D You(people, hackers, w3c, whatever) shouldn't be stubborn, be agile to solve fresh(and old ones surely too) problems, please, just try to consider new ways to fix/deal the CSRF problem because it is extremely common but extremely dangerous either, yet! Here are what I got:

  1. Warnings in browsers. I don't propose it anymore. People don't like this solution.
  2. Educating developers and frameworks. And no "buts" here! Every web developer should know it as well as XSS or SQL Injection! Currently most of devs I ask about CSRF respond a la: "CRFS? CRSS? Dafuq dude? Never heard abt dat".

    It is not funny. I would appreciate your help with "teaching" developers. Ask this question on interviews. Ask your current employees. Ask yourself.

    If anything's unclear - ask me(you can reach me via email homakov@gmail.com I can explain foggy details of CSRF, well, for free. Because I care.)

No more options. Either you fix it easily on the client side(browsers) once and for all or you teach everyone CSRF carefully and in detail(if dev. doesn't understand the problem fully - Sub-problem 2 happens).

It seems people chose 2nd options - OK I will play along. I will do my best to carry explanation to every developer I meet :)

Sub problems I found during the research:

  • Currently lots of frameworks have it out of box. And lots of frameworks don't.  Security is never an option, it must be default - this is Rails' security ideology. 99.99% frameworks and apps must have kind of authenticity_token in every POST request(no matter in post body or in URL - as e.g. 4sq deals with it ).

    When I see on stack overflow smth like THIS I wonder Y People No RTFM. If you don't know what protect_from_forgery means - google it, skipping necessary filter is so lame!


GET should only retrieve data.
(from http://en.wikipedia.org/wiki/TRACE_(HTTP)#Request_methods) Requests using GET should only retrieve data and should have no other effect. Logout(as in showcase with google) is other effect. Logging in - too. Posting message on behalf of user's account(as in yfrog case) is really other effect.
Never(only if you know exactly why it's a last available option) use GET for state-changing requests. Period.

Always verify token for state-changing requests.
Apps must have sort of verify_authenticity_token for every non-GET requests == POST-based requests(it's PATCH, PUT, DELETE..). If session[:token] is equal params[:token] than OK else if check fails - 5xx/4xx code. Do not skip the filter anymore, don't be stupid :RAGE:.

I did my best proving the point with theory and practice but no success. I'm done and this topic is over for me - but don't be surprised by posts "Found csrf vulns in 20 popular websites" from guys like me in a while, but you can still be surprised by losing $ from your %internet bank name% account.

Thanks for reading.