Security Tip: Limiting bcrypt Passwords to 72 Bytes!
[Tip #106] Laravel 12 gives us the ability to reject passwords longer than 72 bytes for bcrypt, but you need to turn it on manually. Oh, and don't forget to add a validation rule, or you'll be throwing suspicious 500 server errors! 😱

As we did when Laravel 11 came out a year ago, we'll be spending the next couple of weeks looking at the security-related changes and improvements in Laravel 12.
The first change I want to focus on relates to a Security Tip we had a couple of weeks ago: Should You Limit Password Lengths?
My conclusion in that tip was that there isn't a compelling reason to limit password lengths when using bcrypt, but the reverse is true too, there isn't a good reason not to limit lengths. So we left it hanging and moved on.
However, Alan Cole decided it was worth doing something about.
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.
He then created a PR for Laravel 12 that modifies the bcrypt hasher to check if the password is longer than 72 bytes (using strlen()
), and throws an exception if the password is too long.
The feature has changed slightly since the PR was merged, so it's now disabled by default, plus you need to specify the length limit for the password (even though it's always going to be 72).
To enable it in your apps, you can either set BCRYPT_LIMIT=72
in your .env
or set the bcrypt.limit
to 72
in your config/hashing.php
:
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 12),
'verify' => env('HASH_VERIFY', true),
'limit' => env('BCRYPT_LIMIT', 72),
],
config/hashing.php
Once enabled, it'll prevent passwords longer than 72 bytes from being hashed and stored, throwing an InvalidArgumentException
when they are hashed.
This should avoid potential password-length issues in the future by preventing overly long passwords aren't accepted.
500 Server Error
!This is where the PR leaves it, however I would recommend taking it a step further and enabling max length validation rules on your password-related forms. This new limit only throws an exception, so a user submitting a long passwords will hit a 500 Server Error
, with no useful feedback as to why. Adding some validation tells the user why their super-long password isn't working.
That said, Laravel's max
validator uses mb_strlen()
which counts characters, while this limit (and bcrypt) is limited to 72 bytes.
For example:
> strlen('😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈');
= 80
> mb_strlen('😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈😈');
= 20
This can create a potential issue where a password that uses multi-byte characters will pass validation, but still throw the exception when it hits the hasher.
As far as I know, there isn't currently a solution in Laravel for this directly. You will need to implement your own validation rule that uses strlen()
to properly validate password lengths and provide useful feedback to your users.
500
errors, as they indicate the server wasn't expecting the input. This often indicates potential SQL Injection issues, and when thrown on password inputs, it usually indicates terrible password handling! If you found this security tip useful, subscribe to get weekly Security Tips straight to your inbox. Upgrade to a premium subscription for exclusive monthly In Depth articles, or drop a coin in the tip jar to show your support.
When was the last time you had a penetration test? Book a Laravel Security Audit and Penetration Test, or a budget-friendly Security Review!
You can also connect with me on Bluesky, or other socials, and check out Practical Laravel Security, my interactive course designed to boost your Laravel security skills.