BOINC / boinc

Open-source software for volunteer computing and grid computing.
https://boinc.berkeley.edu
GNU Lesser General Public License v3.0
2k stars 444 forks source link

improve password security #1644

Closed davidpanderson closed 6 years ago

davidpanderson commented 8 years ago

Passwords are stored on the server as md5(email+password+salt). If hackers break into a server they can get most passwords fairly easily by brute-force search, since MD5 is fast.

Find a more secure way to store passwords.

SETIguy commented 8 years ago

Whatever the new method is, it needs to be backward compatible (i.e. having a tag to specify the hash algorithm) unless we're going to force every user to change passwords.

On Thu, Sep 8, 2016 at 1:01 PM, David Anderson notifications@github.com wrote:

Passwords are stored on the server as md5(email+password+salt). If hackers break into a server they can get most passwords fairly easily by brute-force search, since MD5 is fast.

Find a more secure way to store passwords.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/BOINC/boinc/issues/1644, or mute the thread https://github.com/notifications/unsubscribe-auth/AKXcsufqjGP94isqdlT_F-JzkaeL_p3Hks5qoGmdgaJpZM4J4ZEk .

Eric Korpela korpela@ssl.berkeley.edu AST:7731^29u18e3

grctest commented 8 years ago

I posted this in the boinc_dev mailing list (Worth reading the email chain) and in my boinc_project mailing list thread a couple days ago but felt that this GitHub issue is relevant & I feel that this is a massive security concern which warrants discussion.


Topic of discussion: The current BOINC project user password hashing process!

Upon creating an account, the user's password is hashed as an md5 & salted with their email address: https://github.com/BOINC/boinc/blob/master/html/user/create_account_action.php#L107

If a BOINC server was fully compromised, the attacker would have access to all user's email addresses in the SQL table (entirely negating the salt's effectiveness) leaving the password only protected by an md5 hash.

I looked up whether or not an md5 password hash is sufficient protection, and the overwhelming response was a resounding no.

Quote from the above thread:

Using salted md5 for passwords is a bad idea. Not because of MD5's cryptographic weaknesses, but because it's fast. This means that an attacker can try billions http://hashcat.net/oclhashcat-plus/of candidate passwords per second on a single GPU.

If an attacker has a few graphics cards and a database dump of the password hash + email fields then they could potentially figure out the password behind the md5 via brute force. With the state of password reuse these days, that could have dire consequences (all other BOINC projects potentially compromised if they use boinstats or even worse their accounts elsewhere such as banking could be at risk).

In PHP v5.5 they introduced simple password hashing functionality (password_hash(), password_verify(), etc) which implements bcrypt which is significantly more secure than an md5 hashing process & it wouldn't be adding crazy amounts of new code nor external libraries to the web server.

https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016 (see the PHP section, pretty simple!)

https://stackoverflow.com/questions/4795385/how-do-you-use-bcrypt-for-hashing-passwords-in-php

I've been informed (in the boinc_dev mailing list) that the BOINC desktop client hashes the password before attempting to authenticate with the web server - that would mean that if I was to upgrade to bcrypt from md5 then I would break login/register compatability?

I also realise that switching to a different password hashing mechanism for an existing BOINC project would be quite difficult - the worst case scenario would be resetting the entire user base's password to force an upgrade to the latest version. Instead of resetting passwords en masse, perhaps we could have a migration phase?

User logs into the website -> user supplied password is hashed and compared to the old password hash, upon matching the web server calculates the new bcrypt password hash from the password provided on login, flip a boolean field stating the user has upgraded to the new password hash mechanism and perhaps empty the old password hash (fully migrated to the new password hash mechanism at this point & skipping the migration process on next login).

Edit: Pseudocode:

  if( user has an old style hash ){
    if( password verifies against old style hash ){
      add a new style hash
      delete the old style hash
      log them in
    }
  } else {
    if( password verifies against new style hash ){
       log them in
    }
  }

If we were to migrate from PHP v5.6 to v7.0+ in the future (would it pose a significant challenge to migrate?), we could potentially switch to Argon2i instead of bcrypt for an even stronger hashing algorithm.

Best regards, CM :)

grctest commented 8 years ago

If I was to increase the minimum(6)&maximum(32) password lengths in my project, would that break compatability with the BOINC account manager client? Thanks.

JackJHarris commented 8 years ago

CM is right bcrypt is the answer

There are currently three algorithms which are safe to use:

  • PBKDF2
  • bcrypt
  • scrypt

http://security.blogoverflow.com/2013/09/about-secure-password-hashing/

From a security perspective, I’d say that bcrypt is the best of the three.

https://medium.com/@mpreziuso/password-hashing-pbkdf2-scrypt-bcrypt-1ef4bb9c19b3#.58tw3t57g

Solution: bcrypt the current MD5 Hashes

$options = [ 'cost' => 10 ]; // http://stackoverflow.com/questions/7622698/bcrypt-how-many-iterations-cost password_hash(md5("$email$password$salt"), PASSWORD_BCRYPT, $options)

Though not exactly backwards compatible, it CAN be upgraded to without requiring users to change their passwords. Brute forcing this would be impossible since the minimum input string length to the bcrypt function would be of length 32 -- the output of md5 Brute Force Possibilities := 36^32

Best, Jack

grctest commented 8 years ago

My only concern with Bcrypt is that as time progresses and consumer computer equipment become more powerful it's advised to increase the 'cost' of Bcrypt password hashing, so perhaps 3 years down the road we'll consider the current default cost of 10-12 as insufficient and we may face migrating password hashing mechanism again. That said, Bcrypt is far better than md5.

lakridserne commented 8 years ago

In my opinion we really don't have a choice, but to migrate the passwords. It shouldn't be backwards compatible - it should just be migrated. Unless there are some kind of external application that needs to be updated for this (I really hope there is not) that makes it impossible.

@grctest We'll probably need to migrate again in the future as computing power gets more powerful. Just as for example SSL have gone from 512->1024->2048 bits - and some also use 4096 bits on SSL nowadays.

grctest commented 8 years ago

Marius made a good point on this topic:

The only downside is that if some hacker has already gotten access to MD5-hashed passwords and has been at work cracking them, then adding a layer of bcrypt on top is not going to help.

By migrating users to the new password hashing mechanism without forcing a password reset you would still be at risk of previously extracted md5's being cracked and revealing the passwords. Only really a concern if a project has been previously hacked (though, would you know?)..

JackJHarris commented 8 years ago

Correct - if your server was 'hacked', then everyone would need to reset their passwords prior to migrating to the new password hashing mechanism.

However, migrating to a more secure password hashing procedure can be done without assuming all current passwords have been compromised.

If you assume that all the md5 hashes are already compromised, it follows that the server housing that information is compromised (otherwise you wouldn't have lost the md5 hashes). Resetting passwords would not be enough to reestablish a secure environment; the server would need to be reinstalled.

With the lack of any evidence of inappropriate access, I believe the cost of taking the default assumption that all md5s are already compromised is just too high.

Therefore, I think it is more prudent to move forward with simply migrating to more secure hashing structure without requiring users to change their passwords by leveraging the existing md5 hashes as inputs to a more secure hashing function such as bcrypt.

grctest commented 7 years ago

Could I tip some GRC to developers to accelerate the implementation of a higher strength password hashing mechanism in BOINC? (Preferably bcrypt or stronger). Or would such a development goal be best pursued solo?

Semi-on-topic: Chasing after argon2i would require upgrading from PHP v5.6 to v7.X, how difficult would this be?

Thanks :)

ChristianBeer commented 7 years ago

As stated above, backwards compatibility is the problem. What do you do with current clients that send a hash the old way? For reference: lib/gui_rpc_client_ops.cpp#L2267

grctest commented 7 years ago

A problem that has been acknowledged by @davidpanderson is the fact that BOINC client versions are not consistent across platforms & some platforms are no longer supported.

Hopefully supported (but not up-to-date) clients (linux/mac/android) could be elevated to the current development version that windows releases are currently at & that we could move towards a new password hashing mechanism with minimal backwards compatability issues.

Clients running on platforms no longer supported will never be able to upgrade password hashing mechanism - we could either go down the route of a mandatory upgrade or completely drop support for these old platforms (potentially removing the app from repos?) We shouldn't be held back from improving the system because of clients on old platforms which are no longer supported, large companies like Microsoft and Apple no longer support these platforms either.

Fair enough there may be a drop off in computing power from these old systems, however new systems running newer operating systems likely have significantly more computing power then these old systems.

Arguably, the password hashing shouldn't be done client side - it prevents individual BOINC projects from switching password hashing mechanisms.

Migrating from the old password hash to the new password hash mechanism for end-users could be as simple as switching them to the new mechanism when they next log in to the BOINC project (rather than forcing a password reset).

ChristianBeer commented 7 years ago

The only unsupported platforms I see in this list are PPC and "older " Linux (which means BOINC compiled with older libc). This is also not really about platform support, this is about the need for users to update the Client software. How should a project change the password hashing algorithm if old Clients (from supported platforms) are still contacting it? What about if a user updates to the new version (with the new hashing) on just some of his hosts?

grctest commented 7 years ago

How should a project change the password hashing algorithm if old Clients (from supported platforms) are still contacting it? What about if a user updates to the new version (with the new hashing) on just some of his hosts?

Could we potentially utilize the notice system to push reminders to the end users that they need to upgrade all of their BOINC clients? What about several notices in the run-up to a mandatory switch-over?

If users refuse to upgrade their clients then potentially we send a notice and cut off their computation? It's certainly not desirable to cut off computation, but by not upgrading their clients they ultimately stall community-wide security upgrades.

Perhaps a future client version could have a pop-up when a new client version is released? Whilst annoying, it could lead to higher rates of client-upgrades & would be less intrusive than an auto-updater.

ChristianBeer commented 7 years ago

Each project already has the means to set a minimum client version and also a deadline when this will be enforced that get's propagated to the users via notices. The percentage of people regularly looking at those is rather small as most people usually install BOINC and then forget about it.

Speaking as part of a bigger project we definitely don't want to cut of people from our project just because they can't update their Clients (because they are using an older OS that does not provide the newer Client). The transition period to get the majority of users to the new client would be long and even then you need to handle the questions and fallout that happens when suddenly the RAC of users drops and they complain in the forums. We have some experience when switching over to SSL connections for the scheduler. This essentially cut of the PPC client and all Windows Clients pre 7.4. There was also the Debian cross-certificate problem that cut of all users with a current Debian installation where we had to wait on the Debian people to fix it. This is all annoying and taking precious time away from doing science.

What should be done now is to make the Client aware of the hash algorithm used by an individual project so it can be told to use something other than the current implementation. This will automatically be propagated by the users and after 2 or 3 years projects can decide to change the hash algorithm on the server based on the then apparent distribution of Client versions. The advantage would be that new projects can choose to only support this new Client but the new Client can still communicate with the old projects.

grctest commented 7 years ago

What should be done now is to make the Client aware of the hash algorithm used by an individual project so it can be told to use something other than the current implementation. This will automatically be propagated by the users and after 2 or 3 years projects can decide to change the hash algorithm on the server based on the then apparent distribution of Client versions. The advantage would be that new projects can choose to only support this new Client but the new Client can still communicate with the old projects.

That sounds like an excellent idea! Perhaps we should encourage projects to send a notice out every few months to users running old clients that they should consider upgrading their client too? Getting 560k users to coordinate is quite the challenge!

davidpanderson commented 7 years ago

This issue can be addressed, as Jack Harris pointed out, without changing clients and without requiring users to do anything. I'll try to get to this soon.

marius311 commented 7 years ago

@davidpanderson, I think you're imagining simply bcrypting the MD5'ed passwords before storing them in the DB? This should certainly be done since it improves security and does not require client updates nor password resets, as you say.

However, there's still the issue that a hacker with access to a server can just listen to the MD5'ed passwords as they come in (or anyone performing a MITM attack). To fix that, one should update the client to bcrypt passwords before sending them. I think this should certainly be done, and then projects can enforce minimum client versions as they want.

Those fixes should take care of everything except if a project's database is compromised already, which does seem unlikely. Protecting against this would require a forced password reset after switching to bcrypt, and I would say that can be considered later, after the first two things are done.

davidpanderson commented 7 years ago

Yes, that's what I was going to do. I'll do it in a way that accepts bcrypt'd passwords from clients, once we get around to that.

grctest commented 7 years ago

How're things going with this issue?

Semi-off-topic but quite relevant: http://lists.ssl.berkeley.edu/pipermail/boinc_dev/2016-September/022252.html

The original email chain regarding password hashing mechanism strength also included some concerns regarding the use of an 'account key' which if intercepted would permanently compromise an user's account even if they changed their email/pass/username. Is this the case?

grctest commented 7 years ago

bump Thoughts on how we could go about doing this? What our largest hurdles/difficulties would be?

The account keys are quite frightening, they enable permanent compromise of BOINC accounts :(

Would a Gridcoin bounty aid the development/implementation of the discussed changes?

grctest commented 7 years ago

I've published my concerns regarding account keys here: https://github.com/Erkan-Yilmaz/Gridcoin-tasks/issues/106

brevilo commented 6 years ago

I believe this can be closed now, right?