There are some pseudo-random-number generators in PHP: rand(), srand(), mt_rand(), mt_srand(). You can look at their code here.

I understand those functions are insecure, but how insecure are they?

For example, if those functions are used for generation of anti-CSRF tokens, tokens in file download links how easy will it be for attacker to guess those of other user? How he can do it?

Update: The paper I Forgot Your Password: Randomness Attacks Against PHP Applications seems to be a canonical reading on the subject and contains detailed response to this question. However, it's quiet long and complicated so I'd want to see a more short excerpt that will point or show existence of exploit algorithm using which those functions can be broken.

  • 2
    Duplicate of How insecure are non-cryptographic random number generators?
    – Polynomial
    Commented Aug 2, 2012 at 10:09
  • 5
    @Polynomial Not a duplicate. D.W. specifically said in comments that that question is too broad and more specific questions should be asked about other functions. I ask about weaknesses in those exact functions. Commented Aug 2, 2012 at 10:11
  • Fair enough. I'll provide an answer.
    – Polynomial
    Commented Aug 2, 2012 at 10:13
  • If you want more details on the attacks, I updated my answer with additional links that explain some of these attacks. But do understand that some of the attacks do involve some mathematics. That's just how it goes, sometimes.
    – D.W.
    Commented Aug 3, 2012 at 18:04
  • "I want to see a more short excerpt that will point or show existence of exploit algorithm using which those functions can be broken" - The references already show a working attack algorithm, but it's not something you can fit in a fortune cookie. Sometimes attacks are complicated; that's just the way it is. (By the way, given the number of independent sources that state that these PRNGs are broken and insecure, and explain why, I think it would be wise to believe them.)
    – D.W.
    Commented Aug 3, 2012 at 18:44

4 Answers 4


PHP's rand() generator is a based on the system implementation, which is usually a weak LCG or LFSR (see Andrey's comment below). For more info on why these types of generators are bad, take a look at How insecure are non-cryptographic random number generators?

The mt_rand() function uses Mersenne Twister, which isn't much better. You can determine the internal state and all future values after observing just 624 values.

Don't use either in any situation where you require cryptographic-strength randomness, including CSRF / password-equivilent tokens. A better alternative is the openssl_random_pseudo_bytes function, or reading from /dev/urandom. You could also look into implementing Blum Blum Shub, which is a strong (albeit slow) PRNG.

EDIT (Feb 2017): As of PHP7 the correct method to generate secure random bytes is the random_bytes() function. For more detailed advice about secure RNGs in a variety of languages, take a look at this article.

  • 1
    PHP's rand() uses internal system implementation. At Linux it's LFSR, not LCG. See section 5.4 in this paper for more details Commented Aug 2, 2012 at 12:02
  • Whoops, I misunderstood then. I'll update.
    – Polynomial
    Commented Aug 2, 2012 at 12:03
  • Bruteforce attack that you outlined in your answer to linked question will be impractical because of state of glibc is 31 word of 32 bits each. Again, see section 5.4 in this paper Commented Aug 2, 2012 at 12:27
  • 2
    Don't use Blum-Blum-Shub. It is totally irrelevant here. Recommending Blum-Blum-Shub is like recommending that the person use Diffie-Hellman: it doesn't solve the problem, and is misleading.
    – D.W.
    Commented Aug 3, 2012 at 16:57
  • 2
    openssl_random_pseudo_bytes(...) has been criticized for using a 'home grown' method to collect random. Please recommend random_bytes instead.
    – Jacco
    Commented Feb 3, 2017 at 13:32

There are now cryptographically secure pseudo-random generators in PHP 7, including random_int and random_bytes. Might be worth checking those out.

  • Sorry, I've just realised how old this question/answer was!
    – Rik Lewis
    Commented Feb 3, 2017 at 13:05
  • Don't be sorry for adding new, relevant information to an old question. That is one of the reasons StackOverflow is so good: questions are never locked to prevent new information as it surfaces (so long as they follow the site guidelines). Your insight is valuable, thanks for posting.
    – Dan
    Commented Feb 3, 2017 at 13:57

All of the PRNGs you listed are insecure. Anything dealing with security (sessions, tokens, secrets) requires a CSPRNG. Here are a list of suitable alternatives:

  • mcrypt_create_iv() - Uses /dev/urandom on *NIX and the built-in crypto platform on Windows. Requires the 'mcrypt' extension.
  • /dev/urandom - Requires a *NIX host.
  • openssl_random_pseudo_bytes() - Requires the 'openssl' extension.
  • http://barebonescms.com/documentation/csprng/ - A cross-platform solution that uses whatever is available plus a number of trusted remote web hosts that generate true random data.

As to your question regarding the paper, whatever algorithm you might come up with to generate a random string has probably been done before and the source code is likely available somewhere. If a PRNG is seeded with the current system clock in microsecond resolution, the search space is drastically reduced requiring only a few hundred thousand attempts. Combine that with maybe a few hundred common algorithms and you're looking at potentially mere seconds of CPU to reverse-engineer a token and synchronize with a remote system clock. After that, the application's security is hosed.

I guess the question is, will anyone care to hack your website at that level? Finding a SQL injection opportunity is generally a much easier route than trying to reverse-engineer a token scheme. Low-hanging fruit is more desirable to a hacker.

  • 2
    While mcrypt_create_iv is a good source of crypto-quality random, the MCrypt functions are abandonware, don't use them anymore. openssl_random_pseudo_bytes has been criticized for using a 'home grown' method to collect random. Since PHP7, random_bytes is the preferred, cross-platform, source for crypto quality random. On linux platforms, it uses /dev/urandom as its source.
    – Jacco
    Commented Feb 3, 2017 at 13:36

Those are all insecure. None of them are suitable for use in a CSRF token, or any other application requiring cryptographic strength. If you want more details why you should not use these methods, see the following resources:

You should instead use random_bytes() or /dev/urandom.

See also Better Random Numbers in PHP using /dev/urandom.

  • 1
    The cross-platform implementation in PHP for crypto quality random is random_bytes. On linux platforms it uses /dev/urandom as its source
    – Jacco
    Commented Feb 3, 2017 at 13:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .