Security Tip: Should You Limit Password Lengths?

[Tip #101] Password length limits are often a sign of a legacy backend or insecure hashing, but did you know bcrypt only hashes the first 72 characters? It raises the question, should we be limiting password lengths when using bcrypt too? πŸ€”

Security Tip: Should You Limit Password Lengths?

Following last week's In Depth article, Five Ways to Fail at Authentication, I was sent a great question via email regarding the bcrypt's 72 character truncation behaviour. It really got me thinking, and I wanted to share my answer and open up a discussion on the topic.

As a quick primer for those who haven't read the article, the bcrypt password hashing algorithm only hashes the first 72 characters of the password. If your password is longer, the remaining characters are ignored.

Let me demonstrate the issue:

> $password = str_repeat('A', 72);
= "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

> $hash = password_hash($password, PASSWORD_BCRYPT);
= "$2y$10$wvsMBJvC/xH0A25Rj2k4gOA2sDwV/De4lfFxWd5ooU18vUpfky17G"

// Compare original password with hashed password
> password_verify($password, $hash);
= true

// Compare original password with "Hello" appended with hashed password
> password_verify($password."Hello", $hash);
= true
πŸ€“
Update: Thanks to Alexander and Phil for reminding me in the comments, bcrypt actually truncates after 72 bytes, not characters. This means using multi-byte characters, like emoji, will result in truncation after less than 72 characters in the password.

Here's the question I received:

The Okta story triggered a long time standing question which I am a little embarrassed to admit to have never researched enough to answer. So here I am seeing if you have the answer for me πŸ˜…

IIRC Laravel also uses bcrypt but generally does not have a limit on the length of the password. Now there might not be an issue allowing a user to submit a password longer than 72 but it's also not more secure to go over that limit.

My question is: should we validate passwords to have a max length of 72 (or some other value) or is it okay to let the user submit whatever length they want (considering a minimum of something reasonable)?

And here's my original answer:

Good question! πŸ€”

I don't know if there is right answer, and you could definitely argue both sides.

One the one hand, a 72 character bcrypt'ed password is going to take an absurdly long time to crack, so it doesn't really matter that anything after 72 characters is dropped.

But you could argue that without knowing the limit, someone who uses a password format with a common prefix across apps would gain less protection as the random part of their password would be shorter (after the prefix) than expected. But that also feels like an absurd example, and defeats the whole point of a password.

Having the 72 character limit screams "I use bcrypt!" to anyone trying to gain intel, but does that really matter either?

I think you could go either way, although I personally wouldn't bother adding the limit in my own apps.

Let's keep digging...

To help gain additional insights into this, I asked "the always accurate oracle of knowledge of everything" (i.e. ChatGPT), and got this back:

It’s not strictly necessary to enforce validation rules to limit passwords to 72 characters for bcrypt, but there are good arguments for doing so, depending on your security requirements and user experience priorities.

It then proceeded to tell me three arguments for limiting password lengths that weren't overly helpful...

#1 User Clarity: Without validation, users with passwords longer than 72 characters might assume their entire password is used for authentication. Truncation could lead to confusion or reduced security if part of the password is ignored.

Ok, so you could argue that by not limiting passwords to 72 characters, there could be confusion with users who expect a longer password to be unique. Likewise a reduced level of security... maybe?

But 72 characters isn't exactly weak by any definition... πŸ™ƒ

#2 Security Risks: If an attacker knows passwords are being truncated, they could exploit this behavior. For example, they might generate multiple long passwords that hash to the same value as a shorter password.

Um, what??

Why would they bother generating passwords longer than 72? Also, that would take an insane amount of time with bcrypt.

That isn't how brute-force attacks work... 🀦

#3 Consistency: Enforcing the limit at the validation level ensures passwords are uniformly handled and aligns with the capabilities of bcrypt.

I mean, I guess so? But realistically, the ability to throw any string into bcrypt and getting a hash out is still uniformly handling the string. It feels like it's grasping at straws here...

It then went on to explain why you might not need to limit password lengths:

#1 Edge Case: Few users create passwords longer than 72 characters, so the practical impact might be minimal.

Agreed. You have to be pretty intentional about your password choices to pick 72+ characters.

Curiously, this actually does a better job of explaining that "User Clarity" argument it tried to use above. Those who try to use 72+ characters are probably doing it intentionally, so informing them of the limit might not be a bad idea.

#2 Password Managers: Users relying on password managers often generate random passwords within reasonable lengths, reducing the likelihood of exceeding the limit.

Isn't this just the previous point?

#3 Transparency: If you educate users that only the first 72 characters are used, you may not need to enforce validation.

What?? Why?? No!! 🀦

This is a terrible idea. Let's teach non-technical folks who already struggle with reusing passwords about a highly technical quirk of a specific password hashing algorithm, so they know not to use super-long passwords, just in case it somehow lowers their security. This is an absurd argument.

Summary

So clearly ChatGPT was useless, I'm throwing this one out to all of you!

What do you think? Should we limit password lengths, or just pass everything in?

Leave a comment on this post or find me on Social Media.


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.