Ticket #28633: 28633.5.patch
File 28633.5.patch, 8.5 KB (added by , 10 years ago) |
---|
-
src/wp-admin/includes/ms.php
From c4c47dab7b703a9ff186f8b610d76af43a99584d Mon Sep 17 00:00:00 2001 From: Scott Arciszewski <scott@resonantcore.net> Date: Thu, 12 Feb 2015 13:21:16 -0500 Subject: [PATCH] Patch round 5. --- src/wp-admin/includes/ms.php | 4 +- src/wp-admin/includes/schema.php | 2 +- src/wp-includes/ms-functions.php | 4 +- src/wp-includes/pluggable.php | 142 +++++++++++++++++++++++++++++++++++++- tests/phpunit/tests/functions.php | 34 +++++++++ 5 files changed, 180 insertions(+), 6 deletions(-) diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php index 71129bb..637acef 100644
a b function update_option_new_admin_email( $old_value, $value ) { 246 246 if ( $value == get_option( 'admin_email' ) || !is_email( $value ) ) 247 247 return; 248 248 249 $hash = md5( $value. time() .mt_rand() );249 $hash = md5( wp_random_bytes(16) . $value. time() .mt_rand() ); 250 250 $new_admin_email = array( 251 251 'hash' => $hash, 252 252 'newemail' => $value … … function send_confirmation_on_profile_email() { 327 327 return; 328 328 } 329 329 330 $hash = md5( $_POST['email'] . time() . mt_rand());330 $hash = bin2hex(wp_random_bytes(16)); 331 331 $new_user_email = array( 332 332 'hash' => $hash, 333 333 '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 c522ab5..2ef1a8a 100644
a b We hope you enjoy your new site. Thanks! 1023 1023 1024 1024 $vhost_ok = false; 1025 1025 $errstr = ''; 1026 $hostname = substr( md5( time() ), 0, 6) . '.' . $domain; // Very random hostname!1026 $hostname = bin2hex( wp_random_bytes(3) ) . '.' . $domain; // Very random hostname! 1027 1027 $page = wp_remote_get( 'http://' . $hostname, array( 'timeout' => 5, 'httpversion' => '1.1' ) ); 1028 1028 if ( is_wp_error( $page ) ) 1029 1029 $errstr = $page->get_error_message(); -
src/wp-includes/ms-functions.php
diff --git a/src/wp-includes/ms-functions.php b/src/wp-includes/ms-functions.php index 0e38638..b3d76bc 100644
a b function wpmu_validate_blog_signup( $blogname, $blog_title, $user = '' ) { 710 710 function wpmu_signup_blog( $domain, $path, $title, $user, $user_email, $meta = array() ) { 711 711 global $wpdb; 712 712 713 $key = substr( md5( time() . rand() . $domain ), 0, 16);713 $key = bin2hex(wp_random_bytes(8)); 714 714 $meta = serialize($meta); 715 715 716 716 $wpdb->insert( $wpdb->signups, array( … … function wpmu_signup_user( $user, $user_email, $meta = array() ) { 745 745 // Format data 746 746 $user = preg_replace( '/\s+/', '', sanitize_user( $user, true ) ); 747 747 $user_email = sanitize_email( $user_email ); 748 $key = substr( md5( time() . rand() . $user_email ), 0, 16);748 $key = bin2hex(wp_random_bytes(8)); 749 749 $meta = serialize($meta); 750 750 751 751 $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 ebb7001..74dbb8e 100644
a b function wp_generate_password( $length = 12, $special_chars = true, $extra_speci 2003 2003 2004 2004 $password = ''; 2005 2005 for ( $i = 0; $i < $length; $i++ ) { 2006 $password .= substr($chars, wp_ rand(0, strlen($chars) - 1), 1);2006 $password .= substr($chars, wp_secure_rand(0, strlen($chars) - 1), 1); 2007 2007 } 2008 2008 2009 2009 /** … … function wp_generate_password( $length = 12, $special_chars = true, $extra_speci 2016 2016 return apply_filters( 'random_password', $password ); 2017 2017 } 2018 2018 endif; 2019 if ( !function_exists('wp_random_bytes') ) : 2020 2021 /** 2022 * Generate a cryptographically secure random string 2023 * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ 2024 * 2025 * @param int $bytes - how many bytes do we want? 2026 */ 2027 function wp_random_bytes($bytes = 32) { 2028 $buf = ''; 2029 /** 2030 * If /dev/urandom is available, let's prefer it over every other method 2031 * 2032 * This should only return false on Windows hosts and in chroot jails 2033 */ 2034 if (is_readable('/dev/urandom')) { 2035 $fp = fopen('/dev/urandom', 'rb'); 2036 stream_set_read_buffer($fp, 0); 2037 if ($fp !== false) { 2038 $buf = fread($fp, $bytes); 2039 fclose($fp); 2040 if ($buf !== FALSE) { 2041 return $buf; 2042 } 2043 } 2044 } 2045 /** 2046 * This is preferable to userspace RNGs (e.g. openssl) 2047 * because it reads directly from /dev/urandom on most OS's, 2048 * and uses Windows's Crypto APIs transparently. 2049 * 2050 * Requires the mcrypt extension be installed/enabled. 2051 */ 2052 if (function_exists('mcrypt_create_iv')) { 2053 $buf = mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); 2054 if($buf !== FALSE) { 2055 return $buf; 2056 } 2057 } 2058 /** 2059 * This is available since PHP 5.3.0 on every PHP install. 2060 */ 2061 if (function_exists('openssl_random_pseudo_bytes')) { 2062 $buf = openssl_random_pseudo_bytes($bytes); 2063 if ($buf !== false) { 2064 return $buf; 2065 } 2066 } 2067 2068 /** 2069 * Windows with PHP < 5.3.0 will not have the function 2070 * openssl_random_pseudo_bytes() available, so let's use 2071 * CAPICOM to work around this deficiency. 2072 * 2073 * When we stop supporting unsupported versions of PHP, 2074 * (i.e. less than 5.5) this should be easily removable. 2075 */ 2076 if (class_exists('\\COM', false)) { 2077 try { 2078 $util = new \COM('CAPICOM.Utilities.1'); 2079 $execs = 0; 2080 /** 2081 * Let's not let it loop forever. If we run N times and fail to 2082 * get N bytes of entropy, then CAPICOM has failed us. 2083 */ 2084 while ($execs < $bytes) { 2085 $buf .= base64_decode($util->GetRandom($bytes, 0)); 2086 if (strlen($buf) > $bytes) { 2087 return substr($buf, 0, $bytes); 2088 } 2089 } 2090 } catch (\Exception($e)) { 2091 unset($e); // Let's not let CAPICOM errors kill our app 2092 } 2093 } 2094 /** 2095 * Okay, at this point, we cannot guarantee a CSPRNG no matter what we 2096 * do. Our only recourse is to return something insecure. 2097 */ 2098 for ($i = 0; $i < $bytes; ++$i) { 2099 $buf .= chr(wp_rand(0, 255)); 2100 } 2101 return $buf; 2102 } 2103 2104 endif; 2105 2106 if ( !function_exists('wp_random_positive_int'): 2107 /** 2108 * Generate a random positive integer between 0 and PHP_INT_MAX 2109 * 2110 * @return int A random positive integer 2111 */ 2112 function wp_random_positive_int() { 2113 $buf = wp_random_bytes(PHP_INT_SIZE); 2114 if($buf === false) { 2115 trigger_error('Random number failure', E_USER_ERROR); 2116 } 2117 2118 $val = 0; 2119 $i = strlen($buf); 2120 2121 do { 2122 $i--; 2123 $val <<= 8; 2124 $val |= ord($buf[$i]); 2125 } while ($i != 0); 2126 2127 return $val & PHP_INT_MAX; 2128 } 2129 endif; 2130 2131 if ( !function_exists('wp_secure_rand') ): 2132 /** 2133 * Generates an unbiased, unpredictably random number 2134 * 2135 * @since x.x.x 2136 * 2137 * @param int $min Lower limit for the generated number 2138 * @param int $max Upper limit for the generated number 2139 * @return int A random number between min and max 2140 */ 2141 function wp_secure_rand( $min = 0, $max = 0) { 2142 $range = $max - $min; 2143 if ($range < 2) { 2144 return $min; 2145 } 2146 $rem = (PHP_INT_MAX - $range + 1) % $range; 2147 do { 2148 $val = wp_random_positive_int(); 2149 if ($val === false) { 2150 // RNG failure 2151 return false; 2152 } 2153 } while ($val > $rem); 2154 return (int) ($min + $val % $range); 2155 } 2156 2157 endif; 2158 2019 2159 2020 2160 if ( !function_exists('wp_rand') ) : 2021 2161 /** -
tests/phpunit/tests/functions.php
diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php index 527780a..81783b6 100644
a b class Tests_Functions extends WP_UnitTestCase { 626 626 $json = wp_json_encode( $data, 0, 1 ); 627 627 $this->assertFalse( $json ); 628 628 } 629 /** 630 * @ticket 28633 631 */ 632 function test_wp_secure_rand() { 633 // Let's load a buffer 634 $buff = array(); 635 636 // How size do we want our test array to be? 637 638 //$size = wp_rand(16,256); 639 $size = 16; 640 641 // We should expect 642 $to_run = 10; 643 644 // 645 for($i = 0; $i < $size; ++$i) { 646 $buff[$i] = 0; 647 } 648 649 $tests = $size * $to_run; 650 651 for($i = 0; $i < $tests; ++$i) { 652 ++$buff[wp_secure_rand(0, $size - 1)]; 653 } 654 655 // With any luck, all of these should be near $to_run. 656 $passed = 0; 657 for($i = 0; $i < $size; ++$i) { 658 $this->assertNotEquals($buff[$i], 0); 659 } 660 661 // We can do statistical tests later to ensure the output is unbiased. 662 } 629 663 }