Problem/Motivation

mt_rand() should not be used for any cryptographic purposes which is also documented on the PHP docs of mt_rand(). Drupal 8 core only uses mt_rand() as a last resort for generating pseudo random numbers in Crypt::randomBytes(). Therefore it does not make sense to seed the random number generator on every single page request. We found out in #2550519: Crypt::randomBytes()/drupal_random_bytes() doesn't actually return cryptographically secure random bytes that the seeding with random bytes from /dev/urandom can cost up to 1 ms of performance on a page request.

The mt_srand() call was orginally introduced in #2140433: Port SA-CORE-2013-003 to Drupal 8.

Proposed resolution

Remove the mt_srand() call from DrupalKernel and move it to the last resirt mt_rand() call in Crypt.php.

Remaining tasks

Patch + review.

User interface changes

none.

API changes

none.

Data model changes

none.

Comments

klausi created an issue. See original summary.

cweagans’s picture

Note that Crypt::randomBytes() currently calls mt_rand() for generating "randomness". This will go away if #2550519: Crypt::randomBytes()/drupal_random_bytes() doesn't actually return cryptographically secure random bytes lands.

heddn’s picture

Issue tags: +Needs backport to D7

Does this need a backport too? Tagging for now.

klausi’s picture

Issue summary: View changes

@cweagans: good point, so we should move the seeding there.

cweagans’s picture

@klausi, We shouldn't be using mt_rand() for crypto. Fixing that alleviates the need for seeding it the way we do if I'm not mistaken. IMO, this can be fixed in #2550519: Crypt::randomBytes()/drupal_random_bytes() doesn't actually return cryptographically secure random bytes since the cryptographic use of mt_rand() is also being removed. The PHP docs for mt_rand() say that there's no need to seed, as it's done automatically, and the only reason that we were seeding it was because we were using it for crypto. We use mt_rand() elsewhere in core, but I think that in those instances, it's okay to just call mt_rand() without doing anything to seed it.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

klausi’s picture

Version: 8.2.x-dev » 7.x-dev
Issue tags: -Needs backport to D7

Does not apply anymore to Drupal 8 because the call was removed already.

heine’s picture

The explicit seeding of mt_rand was added because the default seed was relatively easy to discover using a seed cracker and core and many modules used mt_rand at that time. The intent of the seeding was a blanket protection against the seed cracker, without having to go through all of contrib to fix.

At this point in time -after #2550519: Crypt::randomBytes()/drupal_random_bytes() doesn't actually return cryptographically secure random bytes - mt_rand is only used in core 7.x for file upload progress, replica selection and tests and could be replaced.

Some contributed modules such as legal however still use mt_rand for signature purposes. Others, such as uuid and ctools use mt_rand for uuid generation. These would be immediately exposed to the seed cracker when seeding is removed, and have to switch to drupal_random_bytes.

Status: Active » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.