WordPress.org

Make WordPress Core

Ticket #5367: secure_cookie.4.diff

File secure_cookie.4.diff, 14.4 KB (added by ryan, 8 years ago)
  • wp-login.php

     
    288288default: 
    289289        $user_login = ''; 
    290290        $user_pass = ''; 
    291         $using_cookie = FALSE; 
    292291 
    293292        if ( !isset( $_REQUEST['redirect_to'] ) || is_user_logged_in() ) 
    294293                $redirect_to = 'wp-admin/'; 
     
    296295                $redirect_to = $_REQUEST['redirect_to']; 
    297296 
    298297        if ( $http_post ) { 
     298                // If cookies are disabled we can't log in even with a valid user+pass 
     299                if ( empty($_COOKIE[TEST_COOKIE]) ) 
     300                        $errors['test_cookie'] = __('<strong>ERROR</strong>: WordPress requires Cookies but your browser does not support them or they are blocked.'); 
     301                 
    299302                $user_login = $_POST['log']; 
    300303                $user_login = sanitize_user( $user_login ); 
    301304                $user_pass  = $_POST['pwd']; 
    302305                $rememberme = $_POST['rememberme']; 
     306 
     307                do_action_ref_array('wp_authenticate', array(&$user_login, &$user_pass)); 
    303308        } else { 
    304                 $cookie_login = wp_get_cookie_login(); 
    305                 if ( ! empty($cookie_login) ) { 
    306                         $using_cookie = true; 
    307                         $user_login = $cookie_login['login']; 
    308                         $user_pass = $cookie_login['password']; 
     309                $user = wp_validate_auth_cookie(); 
     310                if ( !$user ) { 
     311                        $errors['expiredsession'] = __('Your session has expired.'); 
     312                } else { 
     313                        $user = new WP_User($user); 
     314 
     315                        // If the user can't edit posts, send them to their profile. 
     316                        if ( !$user->has_cap('edit_posts') && ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' ) ) 
     317                                $redirect_to = get_option('siteurl') . '/wp-admin/profile.php'; 
     318                        wp_safe_redirect($redirect_to); 
     319                        exit(); 
    309320                } 
    310321        } 
    311322 
    312         do_action_ref_array('wp_authenticate', array(&$user_login, &$user_pass)); 
    313  
    314         // If cookies are disabled we can't log in even with a valid user+pass 
    315         if ( $http_post && empty($_COOKIE[TEST_COOKIE]) ) 
    316                 $errors['test_cookie'] = __('<strong>ERROR</strong>: WordPress requires Cookies but your browser does not support them or they are blocked.'); 
    317  
    318323        if ( $user_login && $user_pass && empty( $errors ) ) { 
    319324                $user = new WP_User(0, $user_login); 
    320325 
     
    322327                if ( !$user->has_cap('edit_posts') && ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' ) ) 
    323328                        $redirect_to = get_option('siteurl') . '/wp-admin/profile.php'; 
    324329 
    325                 if ( wp_login($user_login, $user_pass, $using_cookie) ) { 
    326                         if ( !$using_cookie ) 
    327                                 wp_setcookie($user_login, $user_pass, false, '', '', $rememberme); 
     330                if ( wp_login($user_login, $user_pass) ) { 
     331                        wp_set_auth_cookie($user->ID, $rememberme); 
    328332                        do_action('wp_login', $user_login); 
    329333                        wp_safe_redirect($redirect_to); 
    330334                        exit(); 
    331                 } else { 
    332                         if ( $using_cookie ) 
    333                                 $errors['expiredsession'] = __('Your session has expired.'); 
    334335                } 
    335336        } 
    336337 
  • wp-includes/compat.php

     
    147147        } 
    148148} 
    149149 
     150if ( ! function_exists('hash_hmac') ): 
     151function hash_hmac($algo, $data, $key, $raw_output = false) { 
     152        $packs = array('md5' => 'H32', 'sha1' => 'H40'); 
     153 
     154        if ( !isset($packs[$algo]) ) 
     155                return false; 
     156 
     157        $pack = $packs[$algo]; 
     158 
     159        if (strlen($key) > 64) 
     160                $key = pack($pack, $algo($key)); 
     161        else if (strlen($key) < 64) 
     162                $key = str_pad($key, 64, chr(0)); 
     163         
     164        $ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64)); 
     165        $opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64)); 
     166 
     167        return $algo($opad . pack($pack, $algo($ipad . $data))); 
     168} 
     169endif; 
     170 
    150171// Added in PHP 4.3.0? 
    151172if (!defined('IMAGETYPE_GIF')) 
    152173    define('IMAGETYPE_GIF', 1); 
  • wp-includes/pluggable.php

     
    4646        if ( ! empty($current_user) ) 
    4747                return; 
    4848 
    49         if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) || 
    50                 !wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true) ) { 
     49        if ( ! $user = wp_validate_auth_cookie() ) { 
    5150                wp_set_current_user(0); 
    5251                return false; 
    5352        } 
    5453 
    55         $user_login = $_COOKIE[USER_COOKIE]; 
    56         wp_set_current_user(0, $user_login); 
     54        wp_set_current_user($user); 
    5755} 
    5856endif; 
    5957 
     
    293291endif; 
    294292 
    295293if ( !function_exists('wp_login') ) : 
    296 function wp_login($username, $password, $already_md5 = false) { 
     294function wp_login($username, $password, $deprecated = false) { 
    297295        global $wpdb, $error; 
    298296 
    299297        $username = sanitize_user($username); 
     
    313311                return false; 
    314312        } 
    315313 
    316         // If the password is already_md5, it has been double hashed. 
    317         // Otherwise, it is plain text. 
    318         if ( !$already_md5 ) { 
    319                 if ( wp_check_password($password, $login->user_pass) ) { 
    320                         // If using old md5 password, rehash. 
    321                         if ( strlen($login->user_pass) <= 32 ) { 
    322                                 $hash = wp_hash_password($password); 
    323                                 $wpdb->query("UPDATE $wpdb->users SET user_pass = '$hash', user_activation_key = '' WHERE ID = '$login->ID'"); 
    324                                 wp_cache_delete($login->ID, 'users'); 
    325                         } 
     314        if ( !wp_check_password($password, $login->user_pass) ) { 
     315                $error = __('<strong>ERROR</strong>: Incorrect password.'); 
     316                return false; 
     317        } 
    326318 
    327                         return true; 
    328                 } 
     319        // If using old md5 password, rehash. 
     320        if ( strlen($login->user_pass) <= 32 ) { 
     321                $hash = wp_hash_password($password); 
     322                $wpdb->query("UPDATE $wpdb->users SET user_pass = '$hash', user_activation_key = '' WHERE ID = '$login->ID'"); 
     323                wp_cache_delete($login->ID, 'users'); 
     324        } 
     325 
     326        return true; 
     327} 
     328endif; 
     329 
     330if ( !function_exists('wp_validate_auth_cookie') ) : 
     331function wp_validate_auth_cookie($cookie = '') { 
     332        if ( empty($cookie) ) { 
     333                if ( empty($_COOKIE[AUTH_COOKIE]) ) 
     334                        return false; 
     335                $cookie = $_COOKIE[AUTH_COOKIE]; 
     336        } 
     337 
     338        list($username, $expiration, $hmac) = explode('|', $cookie); 
     339 
     340        // Allow a grace period for POST requests 
     341        if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) 
     342                $expiration += 3600; 
     343 
     344        if ( $expiration < time() ) 
     345                return false; 
     346 
     347        $key = wp_hash($username . $expiration); 
     348        $hash = hash_hmac('md5', $username . $expiration, $key); 
     349         
     350        if ( $hmac != $hash ) 
     351                return false; 
     352 
     353        $user = get_userdatabylogin($username); 
     354        if ( ! $user ) 
     355                return false; 
     356 
     357        return $user->ID; 
     358} 
     359endif; 
     360 
     361if ( !function_exists('wp_set_auth_cookie') ) : 
     362function wp_set_auth_cookie($user_id, $remember = false) { 
     363        $user = get_userdata($user_id); 
     364 
     365        if ( $remember ) { 
     366                $expiration = $expire = time() + 1209600; 
    329367        } else { 
    330                 if ( md5($login->user_pass) == $password ) 
    331                         return true; 
     368                $expiration = time() + 172800; 
     369                $expire = 0; 
    332370        } 
    333371 
    334         $error = __('<strong>ERROR</strong>: Incorrect password.'); 
    335         return false; 
     372        $key = wp_hash($user->user_login . $expiration); 
     373        $hash = hash_hmac('md5', $user->user_login . $expiration, $key); 
     374 
     375        $cookie = $user->user_login . '|' . $expiration . '|' . $hash; 
     376 
     377        setcookie(AUTH_COOKIE, $cookie, $expire, COOKIEPATH, COOKIE_DOMAIN); 
     378        if ( COOKIEPATH != SITECOOKIEPATH ) 
     379                setcookie(AUTH_COOKIE, $cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN); 
    336380} 
    337381endif; 
    338382 
     383if ( !function_exists('wp_clear_auth_cookie') ) : 
     384function wp_clear_auth_cookie() { 
     385        setcookie(AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); 
     386        setcookie(AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); 
     387 
     388        // Old cookies 
     389        setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); 
     390        setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); 
     391        setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); 
     392        setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);   
     393} 
     394endif; 
     395 
    339396if ( !function_exists('is_user_logged_in') ) : 
    340397function is_user_logged_in() { 
    341398        $user = wp_get_current_user(); 
     
    350407if ( !function_exists('auth_redirect') ) : 
    351408function auth_redirect() { 
    352409        // Checks if a user is logged in, if not redirects them to the login page 
    353         if ( (!empty($_COOKIE[USER_COOKIE]) && 
    354                                 !wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true)) || 
    355                          (empty($_COOKIE[USER_COOKIE])) ) { 
     410        if ( (!empty($_COOKIE[AUTH_COOKIE]) && 
     411                                !wp_validate_auth_cookie($_COOKIE[AUTH_COOKIE])) || 
     412                         (empty($_COOKIE[AUTH_COOKIE])) ) { 
    356413                nocache_headers(); 
    357414 
    358415                wp_redirect(get_option('siteurl') . '/wp-login.php?redirect_to=' . urlencode($_SERVER['REQUEST_URI'])); 
     
    379436        if ( !wp_verify_nonce( $nonce, $action ) ) { 
    380437                $current_name = ''; 
    381438                if ( ( $current = wp_get_current_user() ) && $current->ID ) 
    382                         $current_name = $current->data->user_login; 
     439                        $current_name = $current->user_login; 
    383440                if ( !$current_name ) 
    384441                        die('-1'); 
    385442 
     443                $auth_cookie = ''; 
    386444                $cookie = explode('; ', urldecode(empty($_POST['cookie']) ? $_GET['cookie'] : $_POST['cookie'])); // AJAX scripts must pass cookie=document.cookie 
    387445                foreach ( $cookie as $tasty ) { 
    388                         if ( false !== strpos($tasty, USER_COOKIE) ) 
    389                                 $user = substr(strstr($tasty, '='), 1); 
    390                         if ( false !== strpos($tasty, PASS_COOKIE) ) 
    391                                 $pass = substr(strstr($tasty, '='), 1); 
     446                        if ( false !== strpos($tasty, AUTH_COOKIE) ) 
     447                                $auth_cookie = substr(strstr($tasty, '='), 1); 
    392448                } 
    393449 
    394                 if ( $current_name != $user || !wp_login( $user, $pass, true ) ) 
     450                if ( $current_name != $user || empty($auth_cookie) || !wp_validate_auth_cookie( $auth_cookie ) ) 
    395451                        die('-1'); 
    396452        } 
    397453        do_action('check_ajax_referer'); 
     
    472528} 
    473529endif; 
    474530 
    475 if ( !function_exists('wp_get_cookie_login') ): 
    476 function wp_get_cookie_login() { 
    477         if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) ) 
    478                 return false; 
    479  
    480         return array('login' => $_COOKIE[USER_COOKIE],  'password' => $_COOKIE[PASS_COOKIE]); 
    481 } 
    482  
    483 endif; 
    484  
    485 if ( !function_exists('wp_setcookie') ) : 
    486 function wp_setcookie($username, $password, $already_md5 = false, $home = '', $siteurl = '', $remember = false) { 
    487         $user = get_userdatabylogin($username); 
    488         if ( !$already_md5) { 
    489                 $password = md5($user->user_pass); // Double hash the password in the cookie. 
    490         } 
    491  
    492         if ( empty($home) ) 
    493                 $cookiepath = COOKIEPATH; 
    494         else 
    495                 $cookiepath = preg_replace('|https?://[^/]+|i', '', $home . '/' ); 
    496  
    497         if ( empty($siteurl) ) { 
    498                 $sitecookiepath = SITECOOKIEPATH; 
    499                 $cookiehash = COOKIEHASH; 
    500         } else { 
    501                 $sitecookiepath = preg_replace('|https?://[^/]+|i', '', $siteurl . '/' ); 
    502                 $cookiehash = md5($siteurl); 
    503         } 
    504  
    505         if ( $remember ) 
    506                 $expire = time() + 31536000; 
    507         else 
    508                 $expire = 0; 
    509  
    510         setcookie(USER_COOKIE, $username, $expire, $cookiepath, COOKIE_DOMAIN); 
    511         setcookie(PASS_COOKIE, $password, $expire, $cookiepath, COOKIE_DOMAIN); 
    512  
    513         if ( $cookiepath != $sitecookiepath ) { 
    514                 setcookie(USER_COOKIE, $username, $expire, $sitecookiepath, COOKIE_DOMAIN); 
    515                 setcookie(PASS_COOKIE, $password, $expire, $sitecookiepath, COOKIE_DOMAIN); 
    516         } 
    517 } 
    518 endif; 
    519  
    520 if ( !function_exists('wp_clearcookie') ) : 
    521 function wp_clearcookie() { 
    522         setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); 
    523         setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); 
    524         setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); 
    525         setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); 
    526 } 
    527 endif; 
    528  
    529531if ( ! function_exists('wp_notify_postauthor') ) : 
    530532function wp_notify_postauthor($comment_id, $comment_type='') { 
    531533        $comment = get_comment($comment_id); 
     
    695697        if ( empty($salt) ) 
    696698                $salt = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH; 
    697699 
    698         return $salt; 
     700        if ( ! defined('SECRET_KEY') ) 
     701                $secret_key = 'shhhh'; 
     702        else 
     703                $secret_key = SECRET_KEY; 
     704                 
     705        return $salt . $secret_key; 
    699706} 
    700707endif; 
    701708 
     
    744751} 
    745752endif; 
    746753 
     754// Deprecated. Use wp_set_auth_cookie() 
     755if ( !function_exists('wp_setcookie') ) : 
     756function wp_setcookie($username, $password = '', $already_md5 = false, $home = '', $siteurl = '', $remember = false) { 
     757        $user = get_userdatabylogin($username); 
     758        wp_set_auth_cookie($user->ID, $remember); 
     759} 
     760endif; 
     761 
     762// Deprecated. Use wp_clear_auth_cookie() 
     763if ( !function_exists('wp_clearcookie') ) : 
     764function wp_clearcookie() { 
     765        wp_clear_auth_cookie(); 
     766} 
     767endif; 
     768 
     769// Deprecated.  No alternative. 
     770if ( !function_exists('wp_get_cookie_login') ): 
     771function wp_get_cookie_login() { 
     772        return false; 
     773} 
     774endif; 
     775 
    747776?> 
  • wp-includes/registration.php

     
    167167        $current_user = wp_get_current_user(); 
    168168        if ( $current_user->id == $ID ) { 
    169169                if ( isset($plaintext_pass) ) { 
    170                         wp_clearcookie(); 
    171                         wp_setcookie($userdata['user_login'], $plaintext_pass); 
     170                        wp_clear_auth_cookie(); 
     171                        wp_set_auth_cookie($ID); 
    172172                } 
    173173        } 
    174174 
  • wp-config-sample.php

     
    66define('DB_HOST', 'localhost');    // 99% chance you won't need to change this value 
    77define('DB_CHARSET', 'utf8'); 
    88define('DB_COLLATE', ''); 
     9define('SECRET_KEY', 'shhhh'); // Change this to something unique 
    910 
    1011// You can have multiple installations in one database if you give each a unique prefix 
    1112$table_prefix  = 'wp_';   // Only numbers, letters, and underscores please! 
  • wp-settings.php

     
    186186} 
    187187 
    188188if ( !defined('USER_COOKIE') ) 
    189         define('USER_COOKIE', 'wordpressuser_'. COOKIEHASH); 
     189        define('USER_COOKIE', 'wordpressuser_' . COOKIEHASH); 
    190190if ( !defined('PASS_COOKIE') ) 
    191         define('PASS_COOKIE', 'wordpresspass_'. COOKIEHASH); 
     191        define('PASS_COOKIE', 'wordpresspass_' . COOKIEHASH); 
     192if ( !defined('AUTH_COOKIE') ) 
     193        define('AUTH_COOKIE', 'wordpress_' . COOKIEHASH); 
    192194if ( !defined('TEST_COOKIE') ) 
    193195        define('TEST_COOKIE', 'wordpress_test_cookie'); 
    194196if ( !defined('COOKIEPATH') ) 
  • wp-admin/includes/misc.php

     
    128128        update_option( 'recently_edited', $oldfiles ); 
    129129} 
    130130 
    131 // If siteurl or home changed, reset cookies and flush rewrite rules. 
     131// If siteurl or home changed, flush rewrite rules. 
    132132function update_home_siteurl( $old_value, $value ) { 
    133133        global $wp_rewrite, $user_login, $user_pass_md5; 
    134134 
     
    137137 
    138138        // If home changed, write rewrite rules to new location. 
    139139        $wp_rewrite->flush_rules(); 
    140         // Clear cookies for old paths. 
    141         wp_clearcookie(); 
    142         // Set cookies for new paths. 
    143         wp_setcookie( $user_login, $user_pass_md5, true, get_option( 'home' ), get_option( 'siteurl' )); 
    144140} 
    145141 
    146142add_action( 'update_option_home', 'update_home_siteurl', 10, 2 );