The OWASP conference proved to be a great ground to bring up this topic of the proposed Rails 2.0 cookie storage structure. I’ve had quite a few conversations with ASP.Net guys since this post comparing the Rails 2.0 Cookie storage verses Microsoft’s ViewState. While I agree there are quite a few similarities, I think there are still a few issues that make this Rails technology choice flawed.
Consider basically any web application for which there is unique data for particular users (like just about any app that requires a login). When the user logs in, the first thing your application typically does is look up the user in the database and stores their unique userID in a session object (if they pass authentication). Your app now should use that session value for each additional database query to only pull up your unique data. There are no additional checks since there should be no way the user can change this ID value… as long as you never send it to the client (I’m talking to you Mr. “Hidden” form tag). The amount of damage you can do by manipulating a value like that, which I believe is very common for any application, is considerably more sever than any attack against ViewState (given any logical implementation of either technology).
Another item that makes the Rails approach flawed is how the password is chosen for the SHA1 hash. It’s great that Rails will not allow a blank “secret” to be used, but this is the only complexity check. My feeling is that the machineKey approach used with ViewState hashing and encryption will yield a much more complex password than what you will find most developers choosing on their own. To prove that point, try out the BustRailsCookie.rb code. You’ll need Ruby installed and either a few trusty wordlists or John the Ripper. After that, just pass in a rails 2.0 cookie with both the encoded value and the hash. The script will first show you the unmarshalled session object, then start the cracking for the server side secret password.
I still think Rails is pretty sweet. Just make sure to update one line in your environmental files if you’re using 2.0. For those of you looking for more info on how Rails stacks up against the OWASP top ten, Heiko Webers has created a fairly in depth and up-to-date guide on the OWASP site. I recommend checking it out.
Ruby Script: BustRailsCookie.rb
Windows Compiled: BustRailsCookie1.1.0.zip
(Note: little problem with the compiled version and pipes. I recommend using the ruby script if you have ruby and rails installed.)
Update (11/25/2007): Well glad this made it to the eyes of DHH on the core mailing list. I guess the “is_admin” flag is a bad choice for an example in Rails. I was hoping it would make things more clear, but my view is even putting the “user_id” in the cookie store session becomes dangerous if someone chooses a weak secret password (and my experience with that is… people choose weak passwords). If it’s something from a dictionary, or easy to brute force, it then allows anyone who cracks it to become any other user in the application. Even with encryption or a strong password, storing the session in a cookie opens up the possibility for an attack against it which is not present in the other session store options. As Heiko pointed out, he’s already found some code with fairly weak secrets set. I guess we’ll see how this plays out in the real world.
Both comments and trackbacks are currently closed.