Sjoerd Langkemper wrote a very interesting read about how PHP rand() works, and how to attack & crack it. Web applications occasionally need to create tokens that are hard to guess: session tokens, CSRF tokens, or the token mailed to you by "forgot password" functionality. These tokens should be cryptographically secure, but they are often made by calling rand() multiple times and transforming the output into a string. His post explores how hard it is to predict a token made with rand().
Never use rand() or mt_rand() for security tokens: the state of the random number generator can be cracked, and then tokens can be predicted. In PHP 7 and later, use random_bytes() or random_int() instead.
I originally wrote this post in 2016, and the research covers PHP 5.x and 7.0. Since PHP 7.1, rand() is an alias of mt_rand(), but neither is cryptographically secure. Since PHP 7.0, random_bytes() and random_int() are the functions to use for tokens.
Predicting tokens made with PHP rand()
His conclusion is clear:
Tokens should be created using a cryptographically secure random number generator.
If tokens are made with rand(), the state of the random number generator can in many cases be cracked trivially, after which tokens can be predicted. On Linux this is a bit harder, but it still doesn't give you secure tokens. On Windows the random number generator is particularly easy to exploit: any state can be cracked within minutes. Read the full analysis at Sjoerd Langkemper's blog: Cracking PHP rand().
Need random strings outside PHP? Use a Bash function to generate a secure random alphanumeric string, or generate pseudorandom passwords with OpenSSL.