[wp-trac] [WordPress Trac] #21022: Use bcrypt for password hashing; updating old hashes

WordPress Trac noreply at wordpress.org
Wed Sep 18 06:51:55 UTC 2019


#21022: Use bcrypt for password hashing; updating old hashes
-------------------------------------------------+-------------------------
 Reporter:  th23                                 |       Owner:  (none)
     Type:  enhancement                          |      Status:  new
 Priority:  normal                               |   Milestone:  Future
                                                 |  Release
Component:  Security                             |     Version:  3.4
 Severity:  major                                |  Resolution:
 Keywords:  2nd-opinion has-patch needs-testing  |     Focuses:
  dev-feedback                                   |
-------------------------------------------------+-------------------------

Comment (by mbijon):

 Funny @paragoninitiativeenterprises, I just found the pointer dereference
 in PHP's bcrypt: https://github.com/php/php-
 src/blob/master/ext/standard/crypt_blowfish.c#L613. Combining crypto
 methods is never a good idea, eh.

 Wish you mentioned the `NUL` dereference in your 1st post here. Good info
 though: https://paragonie.com/blog/2015/04/secure-authentication-php-with-
 long-term-persistence

 For anyone else following ... **ABSOLUTELY DON'T USE...**
 `password_hash($raw_sha256|384|512, PASSWORD_BCYPT);`.

 The vulnerability is a two-step: (1) Raw SHA hashes allow null-bytes as
 valid characters. Then (2) the PHP implementation of bcrypt truncates the
 password-input at the 1st null byte (likely ALL C-based implementations of
 bcrypt do this).

 Or, as @paragoninitiativeenterprises noted in the link just above, there's
 a 1-in-256 chance that the 1st character in a SHA hash is a NUL-byte
 (0.39% chance). Extrapolating, that means there's a 5.9% chance a
 15-character password gets truncated early if you feed a raw SHA directly
 to `password_hash()`.

 So ... do NOT `password_hash( hash( 'SHA_any', $password ) )`.

 ----

 In light of that, I think there are two options:
 1. `password_hash(base64(sha_abc($password)), SOMETHING)`
 2. `password_hash($password, SOMETHING)`

 Before anyone has any knee-spasms again: Note that `bcrypt()` is a PBKDF-
 type cryto. These are sometimes called slow hashes. On the other side, all
 the SHA's are hash-generators or fast hashes.

 In attacker terms, once they get past "easy"
 rainbow/shortening/lengthening/collision vulnerabilities they're left with
 brute force. On a GPU bcrypt's default setup/lengthening/salting yields
 <1,000 attempts/second. On the same GPU, SHA hashing yields ~1,000,000,000
 attempts/second.

 I can't help but worry your bcrypt-sha512-base64 solution will make
 jumping to `PASSWORD-DEFAULT` harder @paragoninitiativeenterprises. But
 heck! it's still 10^6 better than SHA, and way closer to vanilla
 `password_hash()` than we have now.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/21022#comment:121>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list