From 7734b4ac9fb028db0c25b3f2dfb72958593ab453 Mon Sep 17 00:00:00 2001
From: Scott Arciszewski <scott@arciszewski.me>
Date: Mon, 17 Nov 2014 19:59:10 -0500
Subject: [PATCH] Expose a CSPRNG via wp_secure_rand() and use it
---
src/wp-admin/includes/ms.php | 4 ++--
src/wp-admin/includes/schema.php | 2 +-
src/wp-includes/functions.php | 4 ++--
src/wp-includes/ms-functions.php | 4 ++--
src/wp-includes/pluggable.php | 40 +++++++++++++++++++++++++++++++++++++++-
5 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php
index d2201d3..1f5721e 100644
a
|
b
|
function update_option_new_admin_email( $old_value, $value ) { |
215 | 215 | if ( $value == get_option( 'admin_email' ) || !is_email( $value ) ) |
216 | 216 | return; |
217 | 217 | |
218 | | $hash = md5( $value. time() .mt_rand() ); |
| 218 | $hash = md5( wp_secure_rand(16) . $value. time() .mt_rand() ); |
219 | 219 | $new_admin_email = array( |
220 | 220 | 'hash' => $hash, |
221 | 221 | 'newemail' => $value |
… |
… |
function send_confirmation_on_profile_email() { |
285 | 285 | return; |
286 | 286 | } |
287 | 287 | |
288 | | $hash = md5( $_POST['email'] . time() . mt_rand() ); |
| 288 | $hash = md5( wp_secure_rand(16) . $_POST['email'] . time() . mt_rand() ); |
289 | 289 | $new_user_email = array( |
290 | 290 | 'hash' => $hash, |
291 | 291 | 'newemail' => $_POST['email'] |
diff --git a/src/wp-admin/includes/schema.php b/src/wp-admin/includes/schema.php
index 2cfe9e0..6270ae8 100644
a
|
b
|
We hope you enjoy your new site. Thanks! |
1016 | 1016 | |
1017 | 1017 | $vhost_ok = false; |
1018 | 1018 | $errstr = ''; |
1019 | | $hostname = substr( md5( time() ), 0, 6 ) . '.' . $domain; // Very random hostname! |
| 1019 | $hostname = bin2hex( wp_secure_rand(3) ) . '.' . $domain; // Very random hostname! |
1020 | 1020 | $page = wp_remote_get( 'http://' . $hostname, array( 'timeout' => 5, 'httpversion' => '1.1' ) ); |
1021 | 1021 | if ( is_wp_error( $page ) ) |
1022 | 1022 | $errstr = $page->get_error_message(); |
diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php
index b77d59e..23d0993 100644
a
|
b
|
function wp_is_writable( $path ) { |
1668 | 1668 | function win_is_writable( $path ) { |
1669 | 1669 | |
1670 | 1670 | 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_secure_rand(16)) ) . '.tmp'); |
1672 | 1672 | 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_secure_rand(16)) ) . '.tmp' ); |
1674 | 1674 | |
1675 | 1675 | // check tmp file for read/write capabilities |
1676 | 1676 | $should_delete_tmp_file = !file_exists( $path ); |
diff --git a/src/wp-includes/ms-functions.php b/src/wp-includes/ms-functions.php
index b0cd44c..36331cf 100644
a
|
b
|
function wpmu_validate_blog_signup( $blogname, $blog_title, $user = '' ) { |
713 | 713 | function wpmu_signup_blog( $domain, $path, $title, $user, $user_email, $meta = array() ) { |
714 | 714 | global $wpdb; |
715 | 715 | |
716 | | $key = substr( md5( time() . rand() . $domain ), 0, 16 ); |
| 716 | $key = substr( md5( time() . wp_secure_rand(8) . $domain ), 0, 16 ); |
717 | 717 | $meta = serialize($meta); |
718 | 718 | |
719 | 719 | $wpdb->insert( $wpdb->signups, array( |
… |
… |
function wpmu_signup_user( $user, $user_email, $meta = array() ) { |
748 | 748 | // Format data |
749 | 749 | $user = preg_replace( '/\s+/', '', sanitize_user( $user, true ) ); |
750 | 750 | $user_email = sanitize_email( $user_email ); |
751 | | $key = substr( md5( time() . rand() . $user_email ), 0, 16 ); |
| 751 | $key = substr( md5( time() . wp_secure_rand(8) . $user_email ), 0, 16 ); |
752 | 752 | $meta = serialize($meta); |
753 | 753 | |
754 | 754 | $wpdb->insert( $wpdb->signups, array( |
diff --git a/src/wp-includes/pluggable.php b/src/wp-includes/pluggable.php
index 22c1935..21dc246 100644
a
|
b
|
function wp_generate_password( $length = 12, $special_chars = true, $extra_speci |
2004 | 2004 | } |
2005 | 2005 | endif; |
2006 | 2006 | |
| 2007 | if ( !function_exists('wp_secure_rand') ) : |
| 2008 | /** |
| 2009 | * Generate a cryptographically secure random string |
| 2010 | * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ |
| 2011 | * |
| 2012 | * @param int $bytes - how many bytes do we want? |
| 2013 | */ |
| 2014 | |
| 2015 | function wp_secure_rand($bytes = 32) { |
| 2016 | $buf = ''; |
| 2017 | // Use /dev/urandom over all other methods |
| 2018 | if (is_readable('/dev/urandom')) { |
| 2019 | $fp = fopen('/dev/urandom', 'rb'); |
| 2020 | if ($fp !== false) { |
| 2021 | $buf = fread($fp, $bytes); |
| 2022 | fclose($fp); |
| 2023 | if ($buf !== FALSE) { |
| 2024 | return $buf; |
| 2025 | } |
| 2026 | } |
| 2027 | } |
| 2028 | if (function_exists('mcrypt_create_iv')) { |
| 2029 | $buf = mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); |
| 2030 | if($buf !== FALSE) { |
| 2031 | return $buf; |
| 2032 | } |
| 2033 | } |
| 2034 | if (function_exists('openssl_random_pseudo_bytes')) { |
| 2035 | $strong = false; |
| 2036 | $buf = openssl_random_pseudo_bytes($bytes, $strong); |
| 2037 | if ($strong) { |
| 2038 | return $buf; |
| 2039 | } |
| 2040 | } |
| 2041 | } |
| 2042 | |
| 2043 | endif; |
| 2044 | |
2007 | 2045 | if ( !function_exists('wp_rand') ) : |
2008 | 2046 | /** |
2009 | 2047 | * Generates a random number |
… |
… |
function wp_rand( $min = 0, $max = 0 ) { |
2024 | 2062 | static $seed = ''; |
2025 | 2063 | else |
2026 | 2064 | $seed = get_transient('random_seed'); |
2027 | | $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed ); |
| 2065 | $rnd_value = md5( wp_secure_rand(16) . uniqid(microtime() . mt_rand(), true ) . $seed ); |
2028 | 2066 | $rnd_value .= sha1($rnd_value); |
2029 | 2067 | $rnd_value .= sha1($rnd_value . $seed); |
2030 | 2068 | $seed = md5($seed . $rnd_value); |