-
Notifications
You must be signed in to change notification settings - Fork 11.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[11.x] Prevents Bcrypt hashing from spilling over and creating insecure hashes. #54494
Conversation
While this is a security fix it may break existing applications running Laravel 11. Therefore, I suggest that you target Laravel 12 for the new default behavior of throwing an exception and you may create another pull request to backport it to Laravel 11 with opt-in flag to enable exception throwing. |
Could do, happy to have a config value in hashing.php, but this only affects newly created hashes and not stored ones, they'll all still validate (albeit insecurely) so, I think we're probably okay, no? |
Co-authored-by: Sebastian Hädrich <[email protected]>
I think since doesn't actually matter much for the typical user password storage scenario where you aren't stuffing passwords with other values, I would rather table this for Laravel 12 or even make it configurable. |
Okay, but people use Hash::make for way more than passwords 🤷 |
The Okta issue wasn't due to raw passwords being 72+ bytes. They were prepending usernames to passwords when generating cache tokens - which is a completely custom and unusual use-case. It doesn't really apply here.
|
I've seen people in userland use Hash::make for all kinds of "encrypted" values, including with appended prefixes (which could in theory spill over 72) but also, I just thought since bcrypt in PHP is broken, why not do this just in case, basically no overhead and it "polyfills" the broken implementation. But clearly I'm alone. 🤷 |
I don't think the issue is unique to PHP though? My understanding is that it's the underlying Blowfish algo, and not unique to PHP. Please don't misunderstand me, I'm not opposed to the change, but I just don't see a big need for it. I actually asked the question recently over on https://securinglaravel.com/security-tip-should-you-limit-password-lengths/, but there wasn't really a clear consensus from the various discussions it spawned. That said, if you think it's important, I'd suggest following Taylor's recommendation and PRing it into 12 so it can be discussed in that context. I'd be interested to see what sort of discussion it creates, and will happily share the link to get more feedback on it. 🙂 |
I'll give it a go tomorrow. Yes it's not unique to PHP, but lots of libraries (in other languages) do add the additional check on top of the system implementation, because frankly why not? Laravel is a "Batteries Included" framework, and if we can do things that help developers make safer tools, I think we should. A check as simple and low rent as this just seems like such a no brainer. |
An edited version that uses a config value to enable / disable the check, targeted at Laravel 12. /cc @taylorotwell and @valorin |
Recently Okta had a security incident created by them using bcrypt hashes that were over 72 chars in length, bcrypt implementations generally allow strings longer than 72 charachters, but simply omit the characters over that length. This can lead to predictable hashes if you can "stuff" the string with 72 known characters.
Take this simple example from Laravel Framework 11.41.3.
Running this, should return us
Hashes do not match, bcrypt is not vulnerable to spill over
because$hash_two
should not be the same as$computed_hash_one
but it doesn't, it returnsHashes match, bcrypt is vulnerable to spill over
because of the spill over.This change, very simply rejects strings longer than 72 chars, when passed to
Hash::make()
when using Bcrypt.Running the same code above after my change, throws an exception instead of silently failing.
Resources