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:
- Warnings in browsers. I don't propose it anymore. People don't like this solution.
- 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!
MUST READ rules
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.