portable perspectives

a blog about programming, life, universe and everything

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?

AddThis Social Bookmark Button

8 Responses to “ActsAsAuthenticated, insecure by default?”

  1. Xavier Noria Says:

    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.

  2. mfp Says:

    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.

  3. riffraff Says:

    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?

  4. Xavier Noria Says:

    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.

  5. Coda Hale Says:

    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.

  6. riffraff Says:

    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 :)

  7. RJ Says:

    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.

  8. riffraff Says:

    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?

Sorry, comments are closed for this article.