password_hash() and the bcrypt 72-byte limit
The PHP manual warns that with PASSWORD_BCRYPT the password argument is truncated to a
maximum of 72 bytes. Bytes after that point do not affect the hash, and no error is raised.
The limit is in bytes, not characters, so multibyte UTF-8 input reaches it sooner.
Why it matters
Any input longer than 72 bytes is subject to the limit. Applications that concatenate other data — nonces, peppers, hex-encoded random values or other hashes — in front of the password can reach the limit sooner. If that prefix fills the 72-byte window, the password stops influencing the hash. The bcrypt RFC cites a FreshRSS authentication bypass (CVE-2025-68402) caused this way.
Related version facts from the manual
| Version | Change |
|---|---|
| PHP 8.0 | password_hash() throws instead of returning false on failure. |
| PHP 8.4 | Default bcrypt cost increased from 10 to 12. |
Mitigations
Passing only the password to bcrypt does not remove its byte limit; application input
validation must account for it explicitly. The PHP manual also documents PASSWORD_ARGON2ID
on builds with Argon2 support. Algorithm availability and application compatibility should
be checked before changing a hashing policy. A
proposed RFC, listed as inactive since 5 October
2026, would deprecate and then reject over-long bcrypt input. Its author has said it is not
worth pursuing further at the moment.
A separate RFC under discussion would add an opt-in
PASSWORD_BCRYPT_SHA256 algorithm that pre-hashes the password with HMAC-SHA256.
Neither proposal is accepted.