• Problem:

    anyone who goes to:

    https://www.yourblog.com/wp-login.php?action=lostpassword

    can attempt to retrieve a password.

    If this behavior is unwanted, here’s a proposed solution for disabling the lost password feature in 2.8.4.

    1. comment out code in wp-login.php, lines 326 and following, and add redirect:

    case 'retrievepassword' :
    /*
    	if ( $http_post ) {
    		$errors = retrieve_password();
    		if ( !is_wp_error($errors) ) {
    			wp_redirect('wp-login.php?checkemail=confirm');
    			exit();
    		}
    	}
    
    	if ( isset($_GET['error']) && 'invalidkey' == $_GET['error'] ) $errors->add('invalidkey', __('Sorry, that key does not appear to be valid.'));
    
    	do_action('lost_password');
    	login_header(__('Lost Password'), '<p class="message">' . __('Please enter your username or e-mail address. You will receive a new password via e-mail.') . '</p>', $errors);
    
    	$user_login = isset($_POST['user_login']) ? stripslashes($_POST['user_login']) : '';
    */
    
    header("location: https://www.yourblog.com/");
    ?>

    2. comments out links to ‘lost your password?’ in wp-login, lines 530 and following:

    <a href="<?php //echo site_url('wp-login.php?action=lostpassword', 'login') ?>" title="<?php //_e('Password Lost and Found') ?>"><?php //_e('Lost your password?') ?></a>
    <?php else : ?>
    <a href="<?php //echo site_url('wp-login.php?action=lostpassword', 'login') ?>" title="<?php //_e('Password Lost and Found') ?>"><?php //_e('Lost your password?') ?></a>
    <?php endif; ?>

    3. modify code in wp-includes/users.php lines 88 and following so ‘lost your password?’ link does not appear after failed login attempt.

    if ( !$userdata ) {
    		//return new WP_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), site_url('wp-login.php?action=lostpassword', 'login')));
    		return new WP_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username.'), site_url('', '')));
    	}
    	$userdata = apply_filters('wp_authenticate_user', $userdata, $password);
    	if ( is_wp_error($userdata) ) {
    		return $userdata;
    	}
    	if ( !wp_check_password($password, $userdata->user_pass, $userdata->ID) ) {
    		//return new WP_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: Incorrect password. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), site_url('wp-login.php?action=lostpassword', 'login')));
    		return new WP_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: Incorrect password.'), site_url('', '')));
    	}

    suggestions for improvement? alternatives?

Viewing 4 replies - 1 through 4 (of 4 total)
  • Good solution. This is helpful for private blogs to extend security as someone can’t try to abuse this feature.

    In step 1, if you add the redirect line right after case ‘retrievepassword’ then you don’t really need to comment out the code right?

    1. Why is this unwanted behavior? It seems to me that users need the ability to reset a forgotten password. Every month we send out a news letter. I can always tell when that goes out because every month five or ten people people reset their passwords. When we first started sending the news letter it was more like twenty or thirty people every month.
    2. How does a user reset a password? Contact the site’s webmaster? That’s not a good solution. Its frustrating and time consuming for the webmaster and the subscriber. Best not to annoy your visitors.
    3. Exactly how is the WP password retrieval system dangerous. A user must remember either a username or the email used to register and must have control over the email account used to register or nothing happens. Perhaps you think there is a flaw in the implementation? If so, what?

    … really seems like a bad idea.

    Deko’s solution on commenting out portions of wp-login.php and wp-includes/user.php (It’s user.php by the way) works great. I tried it on version 2.9.2. However, when explicitly called on the browser’s address bar as ‘www.website.com/wp-login.php?action=lostpassword’, the form still appears. Since we are concerned about extending security, we cannot have a text field like this. We could also remove the entire <form> to </form>. Or better yet, mukeshwani’s suggestion of redirecting seem like the safer approach.

    I added the wp-redirect and exit just after the case. Works great.

    case 'lostpassword' :
    case 'retrievepassword' :
    wp_redirect('wp-login.php'); exit();
    /*
    	if ( $http_post ) {
    		$errors = retrieve_password();
    		if ( !is_wp_error($errors) ) {
    			wp_redirect('wp-login.php?checkemail=confirm');
    			exit();
    		}
    	}
    
    	if ( isset($_GET['error']) && 'invalidkey' == $_GET['error'] ) $errors->add('invalidkey', __('Sorry, that key does not appear to be valid.'));
    
    	do_action('lost_password');
    	login_header(__('Lost Password'), '<p class="message">' . __('Please enter your username or e-mail address. You will receive a new password via e-mail.') . '</p>', $errors);
    
    	$user_login = isset($_POST['user_login']) ? stripslashes($_POST['user_login']) : '';
    */
    
    ?>
    <!--
    <form name="lostpasswordform" id="lostpasswordform" action="<?php echo site_url('wp-login.php?action=lostpassword', 'login_post') ?>" method="post">
    	<p>
    		<label><?php _e('Username or E-mail:') ?><br />
    		<input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr($user_login); ?>" size="20" tabindex="10" /></label>
    	</p>
    <?php do_action('lostpassword_form'); ?>
    	<p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Get New Password'); ?>" tabindex="100" /></p>
    </form>
    -->

    apljdi, it’s wanted behavior if a member trying to retrieve password is legitimately one of your registered members. That’s cool. It’s unwanted when they are.. well, not wanted!

    That doesn’t really answer the question though, do your access logs indicate you’ve had users hitting the login page alot then? Anything to suggest it’s being misused?

    You may prevent the naughty users from brute forcing passwords, but beyond that you’re leaving your good members stuck when they forget their password.

    Admittedly the login form is a little telltale in that when you provide invalid login details it tells you which field is incorrect, ie. if you type in a username that doesn’t exist, the error message tells you it’s an invalid username, which is a little silly.

    However I do believe that this changes in 3.0, and a more generic “Login failed” is displayed, so anyone brute forcing won’t even know if they have a valid name, let alone the password.

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘How to disable lost password feature’ is closed to new replies.