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?

4
  • 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.) Commented Jul 30, 2020 at 11:42
  • 1
    An absent return value would have even more security implications than the hashed empty string. Commented Jul 30, 2020 at 11:43
  • 1
    Because you don't won't to store empty values in your database. Commented Jul 30, 2020 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(). Commented Jul 30, 2020 at 11:53

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

because no one uses NULL bytes in their passwords except people who want to break your login ;-)
That's right @Martin ;-) which is why I always wear suspenders with my belts!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.