1

I've seen some unusual behaviour with password_hash function, maybe i'm wrong but check this:

$var = password_hash(false, PASSWORD_DEFAULT, ['cost' => 10]);
$var = password_hash(null, PASSWORD_DEFAULT, ['cost' => 10]);
var_dump($var);

It returns hashed string like this:

string(60) "$2y$10$MCkQPQcCxL5.ERZ5pJRA.en/MolCwd015OcqNk2zh.ajpicLxONge"

In my opinion it should not return nothing but false?

Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119
Milan
  • 23
  • 3
  • 4
    Why? false and null probably get auto-casted into an empty string here - and empty strings _can_ be hashed. (`d41d8cd98f00b204e9800998ecf8427e` would be the md5 of an empty string, for example.) – CBroe Jul 30 '20 at 11:42
  • 1
    An absent return value would have even more security implications than the hashed empty string. – mario Jul 30 '20 at 11:43
  • 1
    Because you don't won't to store empty values in your database. – Milan Jul 30 '20 at 11:45
  • 6
    IMHO, it's your job as a dev to make sure the value is correct before you pass it to password_hash(). – M. Eriksson Jul 30 '20 at 11:53
  • 2
    If an answer solved your problem, consider accepting the answer. Here's how http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work then return here and do the same with the tick/checkmark till it turns green. This informs the community, a solution was found. Otherwise, others may think the question is still open and may want to post (more) answers. You'll earn points and others will be encouraged to help you. *Welcome to Stack!* – Jay Blanchard Jul 30 '20 at 14:29

1 Answers1

1

Based on this blog you can see that false and NULL values are allowed in passwords and will generate hashes. If you change false or null to an empty string you will also see a hash generated with the leading byte returning the same result. You can test for leading null bytes easily:

$var = password_hash(null, PASSWORD_DEFAULT, ['cost' => 10]);
var_dump($var);

var_dump(password_verify("\0", $var));

with the final var_dump() producing bool(true) showing the you did created a hash using a leading null byte in your password. This is the expected behavior of password_hash() as it will only return NULL on an error.

So this really isn't an issue because no one uses NULL bytes in their passwords. It only becomes an issue when you try to "roll your own" cryptography and the string that you would normally pass wouldn't be a string at all.

Even if you try to set a NULL byte in the string, it is really just a string:

$hashed = password_hash('\0asdfghjkl', PASSWORD_DEFAULT, ['cost' => 10]);
var_dump($hashed);

var_dump(password_verify("\0", $hashed));

Which returns bool(false) from the password_verify().

Bottom Line

Unless you are trying to do something tricky, like pre-hashing your passwords, what you have discovered here is by design. No one enters anything other than strings as their passwords (you could just double-check the password, but don't cleanse them, to make sure it is a string which would be considered wearing suspenders with a belt) and you should never run across a case where NULL bytes are entered.

Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119