A null (zero) character will confuse PHP's password_*
functions, when using bcrypt encryption (which is the default), so it's probably safe to just refuse any password with this character.
$dangerous_pwd = 'foo' . chr(0) . 'bar';
$wrong_login_1 = 'baz';
$wrong_login_2 = 'foo';
$hash = password_hash($dangerous_pwd, PASSWORD_DEFAULT);
if (password_verify($dangerous_pwd, $hash))
echo "this is good!\n";
if (password_verify($wrong_login_1, $hash))
echo "this shouldn't happen! (1)\n";
if (password_verify($wrong_login_2, $hash))
echo "this shouldn't happen, but does! (2)\n";
$wrong_login_1 = 'baz';
$wrong_login_2 = 'foo';
$hash = password_hash($dangerous_pwd, PASSWORD_DEFAULT);
if (password_verify($dangerous_pwd, $hash))
echo "this is good!\n";
if (password_verify($wrong_login_1, $hash))
echo "this shouldn't happen! (1)\n";
if (password_verify($wrong_login_2, $hash))
echo "this shouldn't happen, but does! (2)\n";