Package: wordpress Version: 2.5.1-11 Severity: normal Tags: patch
When using /wp-login.php?action=lostpassword the password reset link received in the email does not work. Following the link results in a "Sorry, that key does not appear to be valid" error. This is caused by "special" charaters being included in the link, which email clients do not treat as part of valid links. IMO, this results in the current stable wordpress package unusable in production settings, as users cannot reset their passwords. This was a known issue for 2.5.1 upstream [1], but the patch fails to fix the problem as 'bad' activation keys are still stored in the database, and not regenerated, resulting in upgrades not fixing the problem for users who have already requested to reset their password. [1] http://core.trac.wordpress.org/changeset/7837 I have attached the recommended patch, also included in the patch is a fix to regenerate activation keys upon password-reset request. Cheers, Alon Swartz -- Website: http://www.turnkeylinux.org Launchpad: https://launchpad.net/~alonswartz
diff -urN wordpress.orig/wp-includes/pluggable.php wordpress/wp-includes/pluggable.php --- wordpress.orig/wp-includes/pluggable.php 2009-03-11 22:57:27.213941000 +0000 +++ wordpress/wp-includes/pluggable.php 2009-03-11 22:58:28.257948246 +0000 @@ -1168,8 +1168,11 @@ * * @return string The random password **/ -function wp_generate_password($length = 12) { - $chars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz01234567...@#$%^&*()"; +function wp_generate_password($length = 12, $special_chars = true) { + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + if ( $special_chars ) + $chars .= '!...@#$%^&*()'; + $password = ''; for ( $i = 0; $i < $length; $i++ ) $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); diff -urN wordpress.orig/wp-login.php wordpress/wp-login.php --- wordpress.orig/wp-login.php 2009-03-11 22:57:13.581901000 +0000 +++ wordpress/wp-login.php 2009-03-11 22:58:13.033892076 +0000 @@ -90,14 +90,12 @@ do_action('retreive_password', $user_login); // Misspelled and deprecated do_action('retrieve_password', $user_login); - $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login)); - if ( empty($key) ) { - // Generate something random for a key... - $key = wp_generate_password(); - do_action('retrieve_password_key', $user_login, $key); - // Now insert the new md5 key into the db - $wpdb->query($wpdb->prepare("UPDATE $wpdb->users SET user_activation_key = %s WHERE user_login = %s", $key, $user_login)); - } + // Generate something random for a key... + $key = wp_generate_password(20, false); + do_action('retrieve_password_key', $user_login, $key); + // Now insert the new md5 key into the db + $wpdb->query($wpdb->prepare("UPDATE $wpdb->users SET user_activation_key = %s WHERE user_login = %s", $key, $user_login)); + $message = __('Someone has asked to reset the password for the following site and username.') . "\r\n\r\n"; $message .= get_option('siteurl') . "\r\n\r\n"; $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";