- From: Giovanni Campagna <scampa.giovanni@gmail.com>
- Date: Mon, 8 Jun 2009 15:52:51 +0200
- To: public-webapps@w3.org
As I understand from various discussions here and from articles around, I've learned that CSRF is a security leak which involves: 1) user visites http://www.mybank.com/login 2) the server sends a cookie, call it MyBankSID, with the login information 3) user visites http://www.dangerous.com/ within the expiration time of cookie 4) the user clickes a link (or sends a form) to http://www.mybank.com/pay?to=hacker 5) the browser sends MyBankSID cookie, which grants access to user's bank account 6) money goes from the user to the attacker To stop CSRF, we need to stop this algorithm at one of these steps. We can stop it at 1), removing state information (like cookies or Authorization headers) for sensitive resources. This is the secret token approach: the session id is embedded in every link and inside every form sent to the web application and continuously changes We can stop it at 2), which involves that the user never visites dangerous web sites. This is our unfortunate situation: sensitive web apps hope that the user never visites web sites which exploit CSRF We can stop it at 3), preventing or asking permission for cross site requests which use non-safe methods (PUT, DELETE and most important POST). This could also mean making always visible what the destination of a link is, before the link is traversed. We can stop it at 4), preventing the user agent from sending automatically state information when the request is originated from a foreign (and possibily untrusted) origin. This means that cookies are not sent for requests that are not same-origin. We can stop it at 5), preventing the website from considering the state information authoritative and thus processing the request associated. This requires an out-of-band indicator for user's intentions, which is currently the Origin header (assuming that the user is conditioned by originating page's content) All of these solution have pros and cons: Solution #1 requires that the server keeps track of the secret id. This can be very difficult to implement for web apps authors and requires a lot of preprocessing on the server side, even for static pages (for example the login page or the contact page). Stopping at 2) is not really a solution, it is just putting the head under the sand. Solution #5 is possible, but requires a new header that proxies or firewalls may strip and current UAs don't send. In addition, it is possible that it will have the same flaws as Referer (which is very similar to Origin), like browser not sending it from https origins. Also, I'm not sure how it would interact with manual entering of URIs, like emails or IMs which say: "paste this into your browser address bar" Then we have solution #4. This may hurt web apps that currently require sensitive cross-site requests, but I'm not sure that there are any, and they could work with automatic redirection to a login page. Architechturally, assuming that the UAs keeps authentication info and automatically sends it is a bad idea that we should not encourage, and so designing web services that require this. Lastly, solution #5 doesn't require any change in the security model or in deployed web apps. The annonyance to the user could be avoided with something like "remember this choice". Yet, the user interface must make very clear where the traversal started, where it will end, and what information the UAs will send authomatically. This is the solution I prefer I hope that this will start a positive discussion, that could maybe improve existing and proposed CSRF prevention techniques. Giovanni
Received on Monday, 8 June 2009 13:53:29 UTC