bcrypt warning on long passwords

php.internals

Rob Landers

1 year ago
Hello internals, I saw the following on hacker-news the other day: https://news.ycombinator.com/item?id=42955176 In the article it talks about how many implementations do not emit a warning, and PHP is one of them (though the author didn't cover php explicitly). You can see this play out here: https://3v4l.org/8ih6O Since adding a warning here would be a BC break, does this need an RFC? I'd be happy to implement this and write the RFC if necessary. — Rob

Kamil Tekiela

1 year ago
Hi, I would say that this is a pretty bad idea. 72 bytes of entropy are quite a lot for *PASSWORDS*. Even if some users use a pass phrase longer than that, the first 72 bytes are enough to provide sufficient security. People who use it for other stuff, like in the linked article, are only to blame themselves. They use the wrong tool for the job. The limitation of bcrypt is very clearly documented[1]. Triggering a warning at runtime wouldn't be useful to the developer. To avoid such a warning they would need to either reject passwords longer than 72 bytes or truncate them before passing it to password_hash. Both approaches provide no additional security or any other value. That would only annoy either the developers or the users. Letting bcrypt use only the first 72 bytes is a very safe and easy solution. No need to overcomplicate it. Regards, Kamil [1]: https://www.php.net/manual/en/function.password-hash.php#refsect1-function.password-hash-parameters

Rob Landers

1 year ago
On Sun, Feb 9, 2025, at 16:20, Kamil Tekiela wrote:
> Hi, > > I would say that this is a pretty bad idea. 72 bytes of entropy are > quite a lot for *PASSWORDS*. Even if some users use a pass phrase > longer than that, the first 72 bytes are enough to provide sufficient > security. People who use it for other stuff, like in the linked > article, are only to blame themselves. They use the wrong tool for the > job. The limitation of bcrypt is very clearly documented[1]. > > Triggering a warning at runtime wouldn't be useful to the developer. > To avoid such a warning they would need to either reject passwords > longer than 72 bytes or truncate them before passing it to > password_hash. Both approaches provide no additional security or any > other value. That would only annoy either the developers or the users. > > Letting bcrypt use only the first 72 bytes is a very safe and easy > solution. No need to overcomplicate it. > > Regards, > Kamil > > [1]: https://www.php.net/manual/en/function.password-hash.php#refsect1-function.password-hash-parameters >
I fully agree with you, however it is also the default password hashing algorithm. People may not read the docs and assume a generic implementation that isn’t constrained. Since it is the default and has constraints, we should probably at least warn people when they are using it wrong. They can then do whatever they want (ignore it, migrate to a different hashing algorithm, turn it into an exception, or adjust their inputs). — Rob

Kamil Tekiela

1 year ago
On Sun, 9 Feb 2025 at 20:58, Rob Landers <rob@bottled.codes> wrote:
> I fully agree with you, however it is also the default password hashing algorithm. People may not read the docs and assume a generic implementation that isn’t constrained. Since it is the default and has constraints, we should probably at least warn people when they are using it wrong. They can then do whatever they want (ignore it, migrate to a different hashing algorithm, turn it into an exception, or adjust their inputs).
My point is that passing a password longer than 72 bytes to password_hash is not wrong. The bcrypt algorithm will work fine and just ignore the unnecessary bytes. It is perfectly normal to let users provide longer passwords and pass them to password_hash unrestricted. What is wrong is when people use password_hash for non-password-related stuff like in the linked article. The problem wasn't that password_hash didn't warn them, but that they prepended the password with non-password information. I expect an oven to cook a chicken, but if I first fill the oven with water, I'd be insane expecting it to work the same way.