WordPress.org

Make WordPress Core

Ticket #28633: 28633.2.patch

File 28633.2.patch, 7.2 KB (added by sarciszewski, 5 years ago)

Updated patch

  • src/wp-admin/includes/ms.php

    diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php
    index a9c62bb..39f2243 100644
    a b function update_option_new_admin_email( $old_value, $value ) { 
    245245        if ( $value == get_option( 'admin_email' ) || !is_email( $value ) )
    246246                return;
    247247
    248         $hash = md5( $value. time() .mt_rand() );
     248        $hash = md5( wp_random_bytes(16) . $value. time() .mt_rand() );
    249249        $new_admin_email = array(
    250250                'hash' => $hash,
    251251                'newemail' => $value
    function send_confirmation_on_profile_email() { 
    323323                        return;
    324324                }
    325325
    326                 $hash = md5( $_POST['email'] . time() . mt_rand() );
     326                $hash = bin2hex(wp_random_bytes(16));
    327327                $new_user_email = array(
    328328                                'hash' => $hash,
    329329                                'newemail' => $_POST['email']
  • src/wp-admin/includes/schema.php

    diff --git a/src/wp-admin/includes/schema.php b/src/wp-admin/includes/schema.php
    index 296a699..db0b2e6 100644
    a b We hope you enjoy your new site. Thanks! 
    10161016
    10171017                $vhost_ok = false;
    10181018                $errstr = '';
    1019                 $hostname = substr( md5( time() ), 0, 6 ) . '.' . $domain; // Very random hostname!
     1019                $hostname = bin2hex( wp_random_bytes(3) ) . '.' . $domain; // Very random hostname!
    10201020                $page = wp_remote_get( 'http://' . $hostname, array( 'timeout' => 5, 'httpversion' => '1.1' ) );
    10211021                if ( is_wp_error( $page ) )
    10221022                        $errstr = $page->get_error_message();
  • src/wp-includes/functions.php

    diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php
    index 76013c9..12393ba 100644
    a b function wp_is_writable( $path ) { 
    16681668function win_is_writable( $path ) {
    16691669
    16701670        if ( $path[strlen( $path ) - 1] == '/' ) // if it looks like a directory, check a random file within the directory
    1671                 return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp');
     1671                return win_is_writable( $path . uniqid( bin2hex(wp_random_bytes(16)) ) . '.tmp');
    16721672        else if ( is_dir( $path ) ) // If it's a directory (and not a file) check a random file within the directory
    1673                 return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' );
     1673                return win_is_writable( $path . '/' . uniqid( bin2hex(wp_random_bytes(16)) ) . '.tmp' );
    16741674
    16751675        // check tmp file for read/write capabilities
    16761676        $should_delete_tmp_file = !file_exists( $path );
  • src/wp-includes/ms-functions.php

    diff --git a/src/wp-includes/ms-functions.php b/src/wp-includes/ms-functions.php
    index 5537fb3..a6a3beb 100644
    a b function wpmu_validate_blog_signup( $blogname, $blog_title, $user = '' ) { 
    713713function wpmu_signup_blog( $domain, $path, $title, $user, $user_email, $meta = array() )  {
    714714        global $wpdb;
    715715
    716         $key = substr( md5( time() . rand() . $domain ), 0, 16 );
     716        $key = substr( md5( time() . wp_random_bytes(8) . $domain ), 0, 16 );
    717717        $meta = serialize($meta);
    718718
    719719        $wpdb->insert( $wpdb->signups, array(
    function wpmu_signup_user( $user, $user_email, $meta = array() ) { 
    748748        // Format data
    749749        $user = preg_replace( '/\s+/', '', sanitize_user( $user, true ) );
    750750        $user_email = sanitize_email( $user_email );
    751         $key = substr( md5( time() . rand() . $user_email ), 0, 16 );
     751        $key = bin2hex(wp_random_bytes(8));
    752752        $meta = serialize($meta);
    753753
    754754        $wpdb->insert( $wpdb->signups, array(
  • src/wp-includes/pluggable.php

    diff --git a/src/wp-includes/pluggable.php b/src/wp-includes/pluggable.php
    index 8f3a5de..67ae2f9 100644
    a b function wp_generate_password( $length = 12, $special_chars = true, $extra_speci 
    19911991
    19921992        $password = '';
    19931993        for ( $i = 0; $i < $length; $i++ ) {
    1994                 $password .= substr($chars, wp_rand(0, strlen($chars) - 1), 1);
     1994                $password .= substr($chars, wp_secure_rand(0, strlen($chars) - 1), 1);
    19951995        }
    19961996
    19971997        /**
    function wp_generate_password( $length = 12, $special_chars = true, $extra_speci 
    20052005}
    20062006endif;
    20072007
     2008if ( !function_exists('wp_random_bytes') ) :
     2009
     2010/**
     2011 * Generate a cryptographically secure random string
     2012 * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
     2013 *
     2014 * @param int $bytes - how many bytes do we want?
     2015 */
     2016function wp_random_bytes($bytes = 32) {
     2017        $buf = '';
     2018        // Use /dev/urandom over all other methods
     2019        if (is_readable('/dev/urandom')) {
     2020                $fp = fopen('/dev/urandom', 'rb');
     2021                if ($fp !== false) {
     2022                        $buf = fread($fp, $bytes);
     2023                        fclose($fp);
     2024                        if ($buf !== FALSE) {
     2025                                return $buf;
     2026                        }
     2027                }
     2028        }
     2029        if (function_exists('mcrypt_create_iv')) {
     2030                $buf = mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM);
     2031                if($buf !== FALSE) {
     2032                        return $buf;
     2033                }
     2034        }
     2035        if (function_exists('openssl_random_pseudo_bytes')) {
     2036                $strong = false;
     2037                $buf = openssl_random_pseudo_bytes($bytes, $strong);
     2038                if ($strong) {
     2039                        return $buf;
     2040                }
     2041        }
     2042}
     2043
     2044endif;
     2045
     2046if ( !function_exists('wp_random_positive_int'):
     2047/**
     2048 * Generate a random positive integer between 0 and PHP_INT_MAX
     2049 *
     2050 * @return int A random positive integer
     2051 */
     2052function wp_random_positive_int() {
     2053    $buf = wp_random_bytes(PHP_INT_SIZE);
     2054    if($buf === false) {
     2055        trigger_error('Random number failure', E_USER_ERROR);
     2056    }
     2057   
     2058    $val = 0;
     2059    $i = strlen($buf);
     2060   
     2061    do {
     2062        $i--;
     2063        $val <<= 8;
     2064        $val |= ord($buf[$i]);
     2065    } while ($i != 0);
     2066
     2067    return $val & PHP_INT_MAX;
     2068}
     2069endif;
     2070   
     2071if ( !function_exists('wp_secure_rand') ):
     2072/**
     2073 * Generates an unbiased, unpredictably random number
     2074 *
     2075 * @since x.x.x
     2076 *
     2077 * @param int $min Lower limit for the generated number
     2078 * @param int $max Upper limit for the generated number
     2079 * @return int A random number between min and max
     2080 */
     2081function wp_secure_rand( $min = 0, $max = 0) {
     2082    $range = $max - $min;
     2083    if ($range < 2) {
     2084        return $min;
     2085    }
     2086    $rem = (PHP_INT_MAX - $range + 1) % $range;
     2087    do {
     2088        $val = wp_random_positive_int();
     2089        if ($val === false) {
     2090            // RNG failure
     2091            return false;
     2092        }
     2093    } while ($val < $rem);
     2094    return (int) ($min + $val % $range);
     2095}
     2096
     2097endif;
     2098
    20082099if ( !function_exists('wp_rand') ) :
    20092100/**
    20102101 * Generates a random number
  • tests/phpunit/tests/functions.php

    diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php
    index 1edd143..312a876 100644
    a b class Tests_Functions extends WP_UnitTestCase { 
    611611                $json = wp_json_encode( $data, 0, 1 );
    612612                $this->assertFalse( $json );
    613613        }
     614   
     615    /**
     616     * @ticket 28633
     617     */
     618    function test_wp_secure_rand() {
     619        // Let's load a buffer
     620        $buff = array();
     621       
     622        // How size do we want our test array to be?
     623       
     624        //$size = wp_rand(16,256);
     625        $size = 16;
     626       
     627        // We should expect
     628        $to_run = 10;
     629       
     630        //
     631        for($i = 0; $i < $size; ++$i) {
     632            $buff[$i] = 0;
     633        }
     634       
     635        $tests = $size * $to_run;
     636       
     637        for($i = 0; $i < $tests; ++$i) {
     638            ++$buff[wp_secure_rand(0, $size - 1)];
     639        }
     640       
     641        // With any luck, all of these should be near $to_run.
     642        $passed = 0;
     643        for($i = 0; $i < $size; ++$i) {
     644            $this->assertNotEquals($buff[$i], 0);
     645        }
     646       
     647        // We can do statistical tests later to ensure the output is unbiased.
     648    }
    614649}