

Discover more from Securing Laravel
Security Tip: New Password Generator
[Tip#37] To celebrate the release of Laravel 10 this week, let's take a look at one of the new (security) features!
Greetings friends! I hope you all enjoyed last week’s In Depth on Stealing Password Tokens with Forwarded Host Poisoning, and the story I shared about my doomed fix. I’m planning to write more emails covering vulnerabilities like that in the future - although hopefully without more doomed fixes!
This week, we’re celebrating the release of Laravel 10 by looking at a cool new security feature, a secure password generator! We’ve talked about Password Generators before, but this is a way to generate secure passwords through a core Laravel helper - rather than reaching for `Str::random(32)`
👉 Security Audits: Want me to hack your app and help you improve your security? 🕵️
Looking to learn more?
⏩ Security Tip #21: Non-production Mail Sending
▶️ In Depth #8: Policy Objects
New Password Generator
When generating new passwords, you need an algorithm that uses a cryptographically secure random generator
to ensure there is enough entropy to keep your passwords unguessable. A good way to do this is to generate lengthy passwords with a significant character set that includes lower case and uppercase letters, numbers, and extra symbols.Laravel 10’s new Password helper lets you do exactly that:
Str::password($length = 32, $letters = true, $numbers = true, $symbols = true, $spaces = false): string;
You can find it over in the docs: https://laravel.com/docs/10.x/helpers#method-str-password.
By default, the helper will return a 32 character incredibly secure password:
> $password = Str::password();
= "eY-j4B<kLf%o/k~x*#&9KUHPU8~!;I?8"
You can change the length, toggle on/off letters, numbers, symbols, and spaces:
> $password = Str::password(
length: 16,
letters: true,
numbers: false,
symbols: true,
spaces: true
);
= "$*|[# S*?/Qxj~W,"
Internally it uses `random_int()`
to securely build the password from it’s extensive character list
So the next time you need to generate a password in your app, you can reach straight for `Str::random()`
.
Thanks Taylor! 😁
I do this all the time!
Rolling-your-own is almost never a good idea!
We talked about this is Tip #19: Cryptographically Secure Randomness.
A fancy word used to discuss how guessable a password is. The more entropy it has, the harder it is to guess. It’s roughly equivalent to how many characters it could include and how long it is, but there is a lot of nuance and complexity that we don’t have time to go into here.
Security Tip: New Password Generator
Along this same line, it might be worth mentioning this recent patch to the Str::random() function that fixes a previous bias towards certain letters due to the use of base64 encoding:
https://github.com/laravel/framework/pull/45916
And when I was reading this article, I checked the implementation that you linked for the new Str::password and I thought it was done in a really clever way. However, it got me wondering how random_int (the built-in PHP function) avoids biasing certain numbers when the size of the range of numbers is not a power of 2. And that brought me to this article below that was an interesting read:
https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
Note, the built-in PHP function does seem to acknowledge and mitigate modulo biasing:
https://github.com/php/php-src/blob/php-8.2.3/ext/random/random.c#L124-L142