Hi all,

I was reading a thread in Slashdot about a recent online MD5 Hash Database which can perform hash lookups. To my surprise i've found that some of my drupal password hashes are actually in the database. I thought that drupal performed hashing with some kind of 'salt' element but i've realized this is not true.

It seems to me a very big security flaw to calculate hashes directly without combining passwords with some other variable. It would be very easy to perform MD5 hashing over say 'user+password' string or any other combination in order to avoid MD5 collisions. I think every application which uses MD5 should *always* take care of this issue, but for a reason I don't know drupal seems not to do it yet.

Any comment will be appreciated.

Comments

Uwe Hermann’s picture

I didn't look very much into this, but you could be right. Please file a bug-report or task so that this doesn't get forgotten.

Uwe.
--
hermann-uwe.de | crazy-hacks.org | unmaintained-free-software.org

Jose Reyero’s picture

I wouldnt say its a security flaw, but for sure, security can be always improved.

To be able to use that hashes on a Drupal site, you first have to know the hashed code, which is not public. And, on the other side, if you can access the database, all the rest is probably pointless.

E150’s picture

In that case, what's the point in using MD5 hashes? You could store your user's passwords as plain text in the database (as they are not public) and in addition being more efficient !!!

In my opinion, nobody has to be able to access the passwords, even the site admins nor anyone with read permissions to the database. Take for example a drupal database in a third party server. The system administrator (or anyone who has gained read privileges in some way) of that system can easily access those hashes and eventually the drupal user's passwords.

The current implementation doesn't guarantee that he will not be using that information for malicious purposes. Not to mention the fact of using the same password for a drupal site and for a private email account, for example.

Yes, as far as I know this is *actually* a security flaw.

Cvbge’s picture

I agree with remarks, and if there's an easy fix for this it should be implemented. It would of course only stop people to getting your passwords from a hash.

The real solution is not to use important passwords (e.g. the same as for your bank) for other web sites.

tostinni’s picture

I read a little time ago documentation from IPS forum about their authentification methode. They are doing this :
converge_pass_hash = md5( md5( converge_pass_salt ) . md5( plain_text_password ) );
Have a look at Authenticating IPB Members.

I'm not pretty sure what we should do about this, because, MD5 strings are not supposed to be available as Jose mentioned...

E150’s picture

Here is another example of how the Gallery2 project developers have gone through this, while keeping compatibility with the old versions authentification schema:

function isCorrectPassword($password) {
	$valid = $this->getHashedPassword();
	$salt = substr($valid, 0, 4);
	/* Support both old (G1 thru 1.4.0; G2 thru alpha-4) and new password schemes: */
	$guess = (strlen($valid) == 32) ? md5($password) : ($salt . md5($salt . $password));
	return !strcmp($guess, $valid);
}

I've not looked into details about how the Drupal authentication code works, but I think a new implementation would not be such a big problem.

What really matters about all this is that MD5 is in fact a valid algorithm criptographycally speaking, but is no longer secure in practice when applied over plaintext passwords given the existence of these databases...

sienadingo’s picture

Hi,

I cannot find this function in the Gallery2 code.

Please tell me what file to find it iin.

Thanks,

Jeff

function isCorrectPassword($password) {
    $valid = $this->getHashedPassword();
    $salt = substr($valid, 0, 4);
    /* Support both old (G1 thru 1.4.0; G2 thru alpha-4) and new password schemes: */
    $guess = (strlen($valid) == 32) ? md5($password) : ($salt . md5($salt . $password));
    return !strcmp($guess, $valid);
}
E150’s picture

Look at the CVS tree of gallery2 in file GalleryUser.class.

Damien Tournoud’s picture

If you want to increase password resilience to lookup in rainbow tables, you have to (1) increase the length of the password and/or (2) increase the size of its charset. The gallery2 code offer very little security enhancement because it basically only increase the length of the password.

The salt is generated in changePassword() :

 $salt = '';
 for ($i = 0; $i < 4; $i++) {
  $char = mt_rand(48, 109);
  $char += ($char > 90) ? 13 : ($char > 57) ? 7 : 0;
  $salt .= chr($char);
 }

Which means that $salt is made of 5 [a-zA-Z0-9] characters.

So md5($salt . $password) has nearly the same charset as typical passwords, and the only difference is that it is 5 characters longer than $password.

That's not better than simply doing md5('drupal'.$password) !

dbcoolio’s picture

Adding Salt isn't about defeating a brute force attack, it's about defeating dictionary and reverse look ups. (so in other words the length doesn't matter) if salt is added then plain word hashes won't appear for reverse lookups. If the attacker knew that 'drupal' was the salt for everything, then they could just run a 'drupal'+dictionary hashing script and then do reverse lookups. The chances of one hash out of 100s matching is pretty high. the strength of salt is that there is a different one for each password, so even if they know the hash and the salt value (which they will have if they've stolen the db table) they will need to rerun their 'salt'+dictionary hashing script for each user, rather than doing it once and then looking at all the users for matching hashes. The salt only needs to be long enough so you have a unique salt value for each user.

sami_k’s picture

If the mechanism is changed it should be well documented at drupaldocs or the handbook as to how to generate a drupal password hash from plaintext. I think one of the major strengths of Drupal is the fact that you can use something as simple as MD5() function to generate the password... This makes importing items in the database easier. If that's changed the information should be clearly available. In the end as far as I am concerned a password is a good as a doorlock, it's there simply to keep people out who respect the law. If someone is determined enough to get your password and can get to the hash I am sure they can find a way to break the salted password. Also, you're not finding "drupal" passwords in the database, you're finding weak passwords hashes that your users have generated with common words.

--
Please read the handbook, search the forums, then ask...
http://drupal.etopian.net (Modules and Drupal Services)

leanazulyoro’s picture

Hi, i recently put online this site: www.clanstug.com.ar, i got a message from an anonimous user that said or warned about passwords being hash crackable using a web intrusion framework, my question is... is this true? and what can be done to correct it right away? looking around a found this module: http://drupal.org/project/phpass, has any of you tried it and can be certain that it works... i mean, because i can implement it but i have no idea if it works, since i dont know how to test it...

thanks

HyperD’s picture

I think could exists a turn around.

Salt is not generated by local system but from an external one. Tell me if I wron,g:

- user starts registration and sends password
- sytem call another server with ONLY a table.
- the main system send to the second uid
- that system generates a random number assigned to that uid and send it back to the main one, storing uid and random number in her table
- main system uses random number as hash, but do not store it in any table. except the first half hashing or better: only md5(hash + password);
- when user logs in and sends her password, main system:
- asks to secondary one the hash
- calculates md5(hash + md5(hash + password))
- takes form his table md5(hash+password)
- repeats md5(hash + md5(hash + password)) and compares the results
- if results are equals ? user is accepted : refused

in this way:
- nor the users nor the provider know the hash
- the second provider have not any clue about content of the single table

but this is a flaw: tehre is too much communication. main server is too exposed

Another manner ( please correct me if I wrong and/or suggest other )
- users registers herself
- hash is stored in the server but also in the hd of the user ( coockie is too exposed ) by javascript
- when users logs in:
- takes her hash from her HD and calculates md5(hash + password)
- sends this to the server and not only md5
- servers does th same and compares the results

Another way is the combination of the two in which hash changes periodically ... to avoid conflicts ? Well I think it's quite easy ... once an hashed pwd is generated, should be compared with all the pwds stored ... if is found an equal ash, simply regenerates the hash of the password to compare and repeat the operation.

I think it's clear: hash must be generated randomly.

What do you think ?

P.S. all these argumentations are good just to talk ... because wherever there is something commonly known, it will possible soon or later decode it and this doesn't take in consideration db merging between different environment as drupal and phpbb for instance even worst with wiki ... each world stays with herself ... the problem is: if I have a site with drupal phpbb and wiki, I have to oblige my users to register them self three times ... i think they will send me and my site to the devil

Tiziano