-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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] Use secure randomness in Arr::random() and Arr::shuffle() #49642
Conversation
I think it is create to add secure randomness. But it might not be needed in all cases. Therefor the question: Are there performance implications for example with the array shuffle method? |
I just ran the following test on my laptop, comparing
So it does have an impact, however I'd argue that secure by default is far more important. Folks assume methods like |
I am on the same page with you. I just wanted people to be aware that security comes with performance tradeoffs and how that might impact their decision for which method to use for the right circumstances. |
Ah, good point, thanks! 🙂 |
Thanks 👍 |
$this->assertNotEquals( | ||
$input, | ||
Arr::shuffle($input) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW: This assertion is going to fail in 1 of 720 cases.
$this->assertNotEquals( | ||
Arr::shuffle($input), | ||
Arr::shuffle($input) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also going to fail in 1 of 720 cases. Combined this gives a failure rate of 1439/518400 for this testcase, which is roughly 1 in 360, which is too high of a false-positive rate for my taste.
Shouldn't this change be in the upgrade guide? The removal of the |
Kinda similar to the idea of |
This is my long-awaited second attempt at #46105.
The implementations of
Arr::random()
andArr::shuffle()
, which are also used byCollection
, currently use insecure randomness fromarray_rand()
andshuffle()
. This replaces those insecure functions with the secureRandomizer::pickArrayKeys()
andRandomizer::shuffleArray()
.As far as I can tell, these are the last two "random" functions in the framework that aren't using secure randomness.
Str::random()
was already random, andStr::password()
suffered from an unsecure shuffle which this PR fixes.I know there was an idea to introduce a standalone
Random
class into Laravel - which is what I've made with https://github.com/valorin/random. Making something like that as part of the Laravel core is still an option, if that is worth doing? This would allow for customRandomizer
Engines to support seeding, etc.(Note, my package supports older versions of PHP, while a Laravel core version would just need to be 8.2+.)
Additionally, as part of this change, I removed the
$seed
functionality fromshuffle()
. If you're relying on seeding randomness, you should be directly implementing seeded randomness functions to ensure nothing changes code wise - rather than relying on third party functions that aren't guaranteed to not change. The old PR failed because a bunch of folks were seeding randomness outside these functions while also expecting specific results from the different functions.For folks who don't want to implement their own seeded random functions, my Random package offers a good solution to seeded randomness: https://github.com/valorin/random.
If seeds are being used for tests - we could look at replicating the random string factory in use for
Str::random()
withinArr
as a testing helper?This is targeted at v11, since it contains backwards compatibility breaks.