ActsAsAuthenticated, insecure by default?
ActsAsAuthenticathed is probably the most widely used (and deployed) plugin for managing user registration/authentication in a rails application.
As everything coming from Rick Olson it's great, giving you a complete authentication system in few steps, with a lot of tweaking points that allows you to make it suitable to your setup.
But I think the default configuration is a bit insecure.
Point is, the default encryption routine (done in #encrypt in model.rb) uses a SHA1 digest to cypher the password. But SHA1 is designed to be a fast digest function, not a password cypher. Moreover, the default password length is restricted in the 4..40 range.
Thus, supposing a user has a password with the standard characters in the [_-a-zA-Z0-9] range, the number of different combination for an acceptable password is 64^4< 17 milions.
This may seem a lot, but if you think about it is not so much, using a dumb ruby script on my old box I can find all the hashes for this kind of password in about three minutes. Yeah, in ruby, with gc kicking in and everything. Having a salt is of no importance, it just avoids finding multiple passwords at once.
Now, if you think that there are things like NSA@Home that will try all the possible passwords of 8 characters in one day (64^8 =~ 3e14), this does not sound really secure.
I'm not a security expert, but I believe this should not be like that. I'd say that to make it a bit more secure you could change the Model#encrypt method to do multiple iterations, say
def self.encrypt(password, salt)
cypher = password
1000.times do
cypher= Digest::SHA1.hexdigest("#{salt}#{cypher}")
end
cypher
end
But even there, I'm not a cryptanalist so I don't know if there is something like "the n iteration of SHA1(string of k elements) may be computed in time O(log(n*k))". Cryptopeople may do stuff like that, all the time, for what I know.
So this is basically a question: is AAA slightly insecure by default? If that is true, what would you use as the encrypt function?
8 Responses to “ActsAsAuthenticated, insecure by default?”
Sorry, comments are closed for this article.
December 24th, 2007 at 03:38 PM
I am no security expert, but I do think your analysis is too simple, and the objections are actually invalid.
AAA uses a per-user salt that prevents dictionary attacks like the one you seem to base your doubts on, see http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes/.
Please be extra careful with posts like this, they could spread FUD unintentionally.
December 24th, 2007 at 04:07 PM
Per-user salt doesn’t prevent brute-force attacks; it only renders rainbow tables ineffective. By the way, the description of rainbow tables in the article you linked to is wrong: there’s a little more to a rainbow table than a list of passwd:hash associations.
4-char passwords are ridiculously unsafe; ActsAsAuthenticathed seems very naïf.
December 24th, 2007 at 04:20 PM
xavier: I was not referring to dictionary attacks, but maybe because I think of dictionary in contrast to brute force. If you equate dictionary to rainbow tables, yeah, I agree that per user salting avoids it, but I was not talking about that. Thanks for the link though, it confirms that you should not use SHA1 to has passwords :)
mfp: I believe the linked post is being simplistic in exchange for clarity?
December 24th, 2007 at 04:28 PM
I mean, the article makes legitimate points.
But for me there’s a distance between being “insecure” and having a default password schema generated in user.rb that may be good enough for some, but that can be made stronger if you wish.
December 24th, 2007 at 10:16 PM
Before you haul off and implement your own key stretching algorithm, check out bcrypt-ruby. It’s a Ruby wrapper for the bcrypt() algorithm developed by the OpenBSD project.
December 25th, 2007 at 01:05 AM
thanks for the hint Coda, actually I just found out today about it earlier today and it seems great.
I’m going to thank you for the actual code as soon as I have it working in my hosting environment :)
December 25th, 2007 at 03:48 AM
There is going to be little difference between hashing the password once or a thousand times because the output generated is going to be completely predictable.
December 25th, 2007 at 11:10 AM
RJ: would you mind explaining a bit more? The output is always going to be predictable, it’s a deterministic function. You mean that the Nth iteration of sha1 is reachable in sublinear time?