Page 1 of 2

Something I just thought of

Posted: Sat Jul 23, 2005 9:14 pm
by josh
What if you had like 10,000 members who's passwords were stored as md5 hash's and you wanted to upgrade to sha1 or sha256 or something, there would be no easy way to do that would there?

And no emailing 10,000 people requiring them to reset there password would not be classified as "easy" to me. (Brute forcing them doesnt count either :-) )

This is hypothetical so don't bother going through great lengths to come up with a solution.

Posted: Sat Jul 23, 2005 9:28 pm
by Ambush Commander
Do it as a person logs in. Whenever they log in, you do the regular comparison, then rehash the password and put it in the new database column. You won't get everybody, but it will maintain backwards compatibility while slowly moving active users to the new hash.

In a worst case scenario, when an algorithm is decisively defeated, you can invalidate all accounts and make people verify their identity via email before letting them set a new password and logging in.

Re: Something I just thought of

Posted: Sat Jul 23, 2005 9:44 pm
by Roja
jshpro2 wrote:What if you had like 10,000 members who's passwords were stored as md5 hash's and you wanted to upgrade to sha1 or sha256 or something, there would be no easy way to do that would there?
Lets assume that you are doing logins in a secure fashion, and already send the password PRE-HASHED via md5. (In other words, the user never sends $password in cleartext.. a javascript md5 library hashes it and replaces it).

In that case, you can add a second hidden form variable to their login. That password field is hashed to make a md5pass, AND a sha-pass. The serverside then checks the md5pass (existing stored password), and ensures it is the correct user (normal auth process). If it is, then it updates the new column ("shapass"), with the submitted shapass.

No cleartext transmission (you clear the original password formfield), two hashes (old and new), validation of existing password hash, and establishing the new password hash.

Most importantly, the user doesn't even know it happened, unless they view source.

Now, then you simply check the number of users that have shapass != '', and when the count is zero, you remove the md5 portion. Or, if they are especially slow to do so, you set a date, and after that point, any users that haven't updated their password have to reset their account manually.

Voila. Secure transition to a new hash.

Posted: Sun Jul 24, 2005 4:32 am
by timvw
I would probably do it as following:

-) Alter table so that 'password' column becomes 'oldpassword' column.
Alter table and add the new 'password' column

-) Change the authentication method to use new 'password'.
If this fails -> Offer user a dialog to update his password as it has expired.

-) After a certain time (or when you notice most updates have happened) send an e-mail to those that haven't updated...

-) After a certain time remove the accounts that still haven't updated.

Posted: Sun Jul 24, 2005 8:07 am
by Ambush Commander
Lets assume that you are doing logins in a secure fashion, and already send the password PRE-HASHED via md5. (In other words, the user never sends $password in cleartext.. a javascript md5 library hashes it and replaces it).
I don't understand how that is more secure. This means that we'll accept any sort of hash: if the database's contents are leaked, then they can use the system's willingness to accept hashes to log on to any account they know the hash for. Am I missing something here?

Posted: Sun Jul 24, 2005 10:09 am
by nielsene
Ambush Commander wrote:
Lets assume that you are doing logins in a secure fashion, and already send the password PRE-HASHED via md5. (In other words, the user never sends $password in cleartext.. a javascript md5 library hashes it and replaces it).
I don't understand how that is more secure. This means that we'll accept any sort of hash: if the database's contents are leaked, then they can use the system's willingness to accept hashes to log on to any account they know the hash for. Am I missing something here?
Its the poor-man's SSL-replacement to avoid sending passwords in the clear. There's different opinion's on whether its more secure or not. You are still comparing the sent value to the (old) hash in the DB, so it must match. You won't accept any hash.

My personal opinion is that if you're worried about network traffic snooping you have to go to full SSL, even if its just a self-signed cert.... or maybe use cacert.org (free, but not recognied by most browsers, though FF should soon), or one of the cheaper, slightly lower-grade ones (not for e-commerce, but good enough for simple logins, etc).

Posted: Sun Jul 24, 2005 12:14 pm
by Ambush Commander
Its the poor-man's SSL-replacement to avoid sending passwords in the clear.
I see.
You won't accept any hash.
You cannot trust anything from the client side. I don't see how selectively trusting hashes would possibly work.

Your comments about SSL seem correct though.

Posted: Sun Jul 24, 2005 12:53 pm
by Roja
Ambush Commander wrote:I don't understand how that is more secure.
Because it avoids passing the password in cleartext, and migrates users to a hash function that is not currently known to be broken/insecure.
Ambush Commander wrote:This means that we'll accept any sort of hash:
Not any. Notice that you only accept 2. Sha, or md5. Also, you only accept md5 until they have an sha pass, and only accept sha once they've migrated.

So at most, its two, and thats only one-time. You aren't "trusting" their hash either - you are checking it against a secret.
Ambush Commander wrote: if the database's contents are leaked, then they can use the system's willingness to accept hashes to log on to any account they know the hash for. Am I missing something here?
No, thats correct. Hashing passwords solves two of eight problems in logins: Cleartext transmission and storage. There are *eight*, each with unique differences, and needs.

Hashed storage and transmission is better because even if you know my hash, you cant figure out a pattern or reuse it on sites that use a different hash, or that dont send the hash directly. Also, if I use patterns in my password (a decent number of users do), then you wouldnt know that while I use "Rojalovesdevnet" here, I probably use "Rojalovesslashdot" at slashdot. Those are all reductions in risk.

You *cannot* solve all 8 security problems in one shot, and thats not what the original poster asked. :)

Posted: Sun Jul 24, 2005 1:04 pm
by Ambush Commander
There are *eight*, each with unique differences, and needs.
If anyone is wondering what that means, I believe http://www.awprofessional.com/articles/ ... Num=1&rl=1 is what Roja is talking about.
Not any. Notice that you only accept 2. Sha, or md5. Also, you only accept md5 until they have an sha pass, and only accept sha once they've migrated.

So at most, its two, and thats only one-time. You aren't "trusting" their hash either - you are checking it against a secret.
Hmm.. we're not on the same channel. I'm saying that if the passwords are leaked, well, if you stored hashed versions, then it's not that bad right? So if the system accepts hashes for a direct check with the value in the database: eg:

hash_sent == hash_in_database

rather than

hash(password) == hash_in_database

with the hash() a mandatory function applied to all incoming data. For the JavaScript implementation, there's no guarantee that the hash was the result of the JavaScript operation, maybe it was injected into the request.

In the end, however, this method is simply an extra security measure, I guess. If the end user doesn't support Javascript, you can always fall back to cleartext transmission, and in the event the hash is sniffed out, at least the password is safe.

Posted: Sun Jul 24, 2005 10:44 pm
by Roja
Ambush Commander wrote: If anyone is wondering what that means, I believe http://www.awprofessional.com/articles/ ... Num=1&rl=1 is what Roja is talking about.
Sorry, no. I've talked about the different steps to a secure login system in roughly a dozen threads here on the forums.. each time someone asks a question something like "Yeah, but step one doesn't solve steps two through eight - SO ITS INSECURE!", which is like saying that if flour and milk don't make cake, nothing can.
Ambush Commander wrote: Hmm.. we're not on the same channel. I'm saying that if the passwords are leaked, well, if you stored hashed versions, then it's not that bad right?
Its "less bad" than if you stored and sent the passwords cleartext.
Ambush Commander wrote: So if the system accepts hashes for a direct check with the value in the database: eg:

hash_sent == hash_in_database

rather than

hash(password) == hash_in_database

with the hash() a mandatory function applied to all incoming data. For the JavaScript implementation, there's no guarantee that the hash was the result of the JavaScript operation, maybe it was injected into the request.
If you DONT use javascript, then you can be sure that the password *IS* being sent in cleartext. Thats bad. Sniffing on the network is extremely common these days, especially on broadband connections. Thats why I recommend js hashing.

If the user doesn't use js hashing, you'll know immediately - the $_POST['password'] will have a value, and the $_POST['hashed_pass'] wont! (Let alone be either 32 or 40 characters depending on the hash).
Ambush Commander wrote: In the end, however, this method is simply an extra security measure, I guess. If the end user doesn't support Javascript, you can always fall back to cleartext transmission, and in the event the hash is sniffed out, at least the password is safe.
The password isn't safe. If the password is sent cleartext, it is likely to be compromised, and then the hash is automatically applied to it. Thats why cleartext transmission is very bad. Its step #1. :)

(*ALL* of the above assumes a lack of ssl. SSL > hash-hackery. :) )

Posted: Sun Jul 24, 2005 10:59 pm
by nielsene
Roja wrote:
Ambush Commander wrote: If anyone is wondering what that means, I believe http://www.awprofessional.com/articles/ ... Num=1&rl=1 is what Roja is talking about.
Sorry, no. I've talked about the different steps to a secure login system in roughly a dozen threads here on the forums.. each time someone asks a question something like "Yeah, but step one doesn't solve steps two through eight - SO ITS INSECURE!", which is like saying that if flour and milk don't make cake, nothing can.
I've just searched through many of your past threads, can you point me to one where you list the 8 steps you consider for a login system?

I agree with you in principle that its stupid to throw out everything if its not perfect. I'm less comfortable about the JavaScript hash suggestions -- I'm one of the people who doesn't like to have JS enabled. If a site requires a real login, I expect SSL. Sites with "fake SSL", which I consider the hash method to be, normally feel *less* secure than a normal cleartext site -- most of them are seriously broken in other ways and think they are being "smart". Now'd I'd trust your sites, since you understand what you're doing and why. But I'm afraid many will take it as a golden bullet solution....

Posted: Mon Jul 25, 2005 1:18 am
by m3mn0n
Moved to PHP Theory & Design.

Interesting discussion. Do carry on! :)

Posted: Mon Jul 25, 2005 3:21 am
by josh
The CHAP login system works by combining the password with a random number, taking the hash of that then sending it.
http://pajhome.org.uk/crypt/md5/auth.html
http://pajhome.org.uk/crypt/md5/chaplogin.html

He has code on there, it would be very effective to implement this in PHP. His system looks pretty solid does it not?

The only thing that I saw on there that did not hold ground was:
We can simply repeat the MD5 operation many times, and the attacker will have to do the same for each password. Informal experiments show that doing 100 repeated hashes in JavaScript does not slow things significantly.
This would effectively increase the chance of a collision, but I think this article was written before a lot of the md5 vulnerabilities were discovered. All in all https is the best option no hands down, but for some of us it's just not possible.

Posted: Mon Jul 25, 2005 6:12 am
by Roja
nielsene wrote:I've just searched through many of your past threads, can you point me to one where you list the 8 steps you consider for a login system?
I was fairly certain I listed them in another thread, but I don't see them. Here are the main threads we've covered this ground in before:

viewtopic.php?p=176943#176943 (This one spells out 6 issues)
viewtopic.php?t=34899 (This one talks in general about it, and gets very confused by the end)
viewtopic.php?t=18633 (This one is solid too)
viewtopic.php?t=16390 (Also worth reading)

There were another handful in addition to those.

From the repetition and the number of times this topic has come up, it sounds like I need to write a solid tutorial that covers all the bases, explaining each of the problems and solutions needed. I was working on one for sitepoint, but never finished it.

I'll see what I can come up with.
nielsene wrote:I agree with you in principle that its stupid to throw out everything if its not perfect. I'm less comfortable about the JavaScript hash suggestions -- I'm one of the people who doesn't like to have JS enabled. If a site requires a real login, I expect SSL.
I don't disagree. SSL is always the ideal. But if SSL isn't available, what then?

Keep in mind that I developed a decent amount of my login code from multiple opensource games. Games which other admins deploy on a *huge* variety of sites stretching from free-hosting, ad-riddled minor 'homepages', all the way to million+ hits per day domains. Some could have SSL, many couldn't.

So, I had to find reasonable solutions that didn't require SSL.
nielsene wrote:Sites with "fake SSL", which I consider the hash method to be, normally feel *less* secure than a normal cleartext site -- most of them are seriously broken in other ways and think they are being "smart". Now'd I'd trust your sites, since you understand what you're doing and why. But I'm afraid many will take it as a golden bullet solution....
To be completely clear: They ARE less secure than SSL. The full explanation about why isn't totally needed, but your gut feeling was right on the money. They are less secure. :)

JS, hashing, and structured logins aren't about replacing SSL. It's about providing the best security you can when SSL isn't available (or in addition to SSL).

Posted: Mon Jul 25, 2005 8:29 am
by nielsene
Roja wrote:From the repetition and the number of times this topic has come up, it sounds like I need to write a solid tutorial that covers all the bases, explaining each of the problems and solutions needed. I was working on one for sitepoint, but never finished it.
I was working on one too before I went stealth for almost a year here.

I was actually planning a series of security tutorials, I think the orginal one is still here someowhere...

Article 1: Terminology (Goals of security and how the different technologies are combinable to obtain them)

Article 2: Intelligent Form Handling (Mainly address all the people who do the foreach($_POST/GET as $key=>$value $$key=$value hack for register globals being off....

Article 3: Secure Forms (Discussing how to use MACs/Hashes to detect client side form tampering of forms, protecting "choice" options -- select/radio/checkbox, MACing list of input names in set order,tests that the form is being submitted from your own site, etc

Article 4: New Account & Login Special Details (What you're talking about)

Article 5: Session security (further locking down the SESSIONID with a proper secure authenticator.