OWASP Top 10 2007 Update RC1 - A5 A6


A5 - Cross-site Request Forgery (CSRF) - Editor's note, I call it XSRF, but I've also seen Session Riding and a couple of other names. Go ahead and get them all confused. Unless all malicious actions are somehow of benefit to the attacker, then I'd probably remove the statement "to the benefit of the attacker". This can also be used for DoS, or getting the carrier to do anything under their own privileges.

The recommendations are pretty sound, but I would certainly flesh them all out. With the first item, you need to focus on those locations where XSRF also exists. Yes - you should get rid of all of them, but start on those - particularly if your request token is specific to the action, not the session. The third bullet should be fleshed out more to specify how to re-authenticate. This can include just asking for the password again, a CAPTCHA, or one-time password. And using GET over POST really doesn't do much at all to help.

A6 Information Leakage and Improper Error Handling - Another sort of catch-all that leads to flaws like A4 (particularly when there's key exposure or filename information). One global 500 configuration I've seen that's very effective is that each application error generates a unique instance ID - I don't mean for the class of error, but the exact occurrence. This way, a user who calls the help desk can give an ID and support teams can trace logs by a unique ID. Of course, this same ID could just be emailed to the support team.

It's also very important that you configure every layer of your error handling to look the same. For example, exceptions handled by Struts can be configured in the struts configuration. But what if the attacker calls a method that makes the framework puke? Then you get a 500 error handled by the app server. Even if you make the error screens look precisely the same, generally an application error in Struts returns a 200, while a Struts error returns a 500 - so you'll want to make sure your global exception handler throws a 500 and returns no content - this way the app server's 500 will be displayed. (The proof is left as an exercise for the reader).