Reducing CSRF Risk With Tiered Authentication
Friday, August 18th, 2006One of the largest dangers with authentication is that once you are authenticated you’re free to visit any page that sits behind the authentication. That wouldn’t be such a huge risk for web application security except for the fact that cross site request forgeries (CSRF) can force you as a user to bounce around within a website without meaning to (at the mercy of your browser, really). So what should you to do mitigate that risk?
I’m not going to give you the full run down on how to stop CSRF because honestly, it’s a huge mess, and with things like the Expect vulnerability in Flash allowing you to read/write from a host, tons of those old methods are broken anyway. The one thing that hasn’t been broken is user interaction. CSRF works because in general it does not require user interaction. Things that rely on unique numbers outputted only work if you can’d get the user to do an XMLHTTPRequest to read the page and replay it, just like the browser would. Trust me, it works. If the site is cross site scriptable (and they almost all are) the method of using unique strings is pretty broken. But there is another way.
Why can’t we ask the user for something? Something that a scanner cannot scan for or know. A userid is too weak and a known entity, but what about their password? Why not stop them in the middle of the flow and say, “Hey, are you really sure you want to change your password?” It doesn’t require a lot from the user, and it’s something that is impossible to session ride without. Of course, you can phish for the username and password, and get the same effect, but that’s far more difficult than a simple image tag CSRF attack.
Yes, there are problems with this, but let’s think about what you are really trying to solve. The vast majority of your users could use a lower level of authentication for the day to day things they are doing (like posting to a web-board for instance). Maybe they have to log in again to change billing information or request information from other users (which could be used as spam). And maybe there is a third level of authentication that asks the user for a username and password when they are doing something like changing account information that could allow for a compromise (like their mother’s maiden name for instance).
You are talking now about the statistical liklihood that the user is in that state. Most of the time they are only in the first state where they cannot do anything but post. That way the statistical liklihood of being able to force the user to perform a malicious function is a factor of how likely it is that a user is in the appropriate level of authentication (which should be very uncommon). In this way you can reduce your overall attack surface to a vast minority of users without some other attack vector (like phishing or credential tampering). Security in layers could start with something as simple as reducing what your users can do without authenticating again.


