WordPress.org

Forums

Theme My Login
Security hole and bug when trying to reset password (3 posts)

  1. MichaelApproved
    Member
    Posted 11 months ago #

    I recently upgraded an old installation of WP and discovered a bug during the password reset process. Here's the scenario:

    1. Use an old version of WordPress, one that still uses MD5.
    2. Do NOT have Theme My Login installed.
    3. Reset your password to generate an MD5 user_activation_key
    4. Now you should have an activation key with $P$B in it.
    5. Upgrade WP and install Theme My Login
    6. Try to reset your password, it will fail.

    There are two problems here. First problem happens because there is a preg_replace filter happening on the key in check_password_reset_key. That breaks when trying to validate old user_activation_keys which have $P$B in them.

    However, the real problem is that a new user_activation_key is not being generated on each request. TML looks for an existing user_activation_key and uses that instead of always generating a new key. By not generating a new key with each new password reset request, TML creates a security risk that allows anyone with an old password reset link to keep resetting the password. That's a major problem if someone had their email hacked. The hacker can keep using the old reset link to generate a new password and break into the account.

    Everything will be fixed by always generating a new user_activation_key so the old one will no longer be valid. By generating a new key, the old MD5 hashed keys will be regenerated and the security hole will be patched.

    This can be done by removing lines 1041, 1042 and 1048 in class-theme-my-login.php which are related to using an existing key. Removing those lines will force a new key to always be generated.

    You should also remove the reverence to MD5 in the comment in line 1046 since it is not relevant. There is no hashing happening to the generated key, it's just a random string.

    My current work around is to add an action on retrieve_password that creates a new key for the user_login but the plugin should be doing this so other installations will be patched as well. For anyone looking to do this too, you can put the code below in your functions.php file.

    Thanks for creating the plugin! We appreciate the work you put into it.

    function my_action_retrieve_password($user_login) {
    		global $wpdb;
    
    		// Generate something random for a key...
    		$key = wp_generate_password( 20, false );
    
    		do_action( 'retrieve_password_key', $user_login, $key );
    
    		$wpdb->update( $wpdb->users, array( 'user_activation_key' => $key ), array( 'user_login' => $user_login ) );
    	}
    add_action('retrieve_password', 'my_action_retrieve_password');

    https://wordpress.org/plugins/theme-my-login/

  2. PurpleEdge
    Member
    Posted 11 months ago #

    With a clean install of wp and tml...

    The key is reset/cleared when the user resets their password? If they don't reset their password then the old key is retained.

    The email goes to the user's email address.

    ...is this a problem?

  3. MichaelApproved
    Member
    Posted 9 months ago #

    Not everyone installs TML on a clean installation of WP. Many people, including myself, add TML to existing installations. That leaves the old MD5 style reset key for the user, causing the preg_replace bug. TML resetting passwords is not compatible with older accounts.

    I see what you're saying about clearing the key on password reset. That does sound better. Ideally, the reset key would expire after a few hours/days but that's a different story.

Reply

You must log in to post.

About this Plugin

  • Theme My Login
  • Frequently Asked Questions
  • Support Threads
  • Reviews

About this Topic