WordPress User Security

Out-the-box, WordPress has a weakness when it comes to user security.

Attempts to login with a valid username (but incorrect password) gives away that an account exists with that username; and author archives use the user login as the URL in the format site.com/author/{username}

I’ve put together a quick plugin that remedies these issues; this:

  • Disguises login errors with a generic message
  • Disables author archives
  • Changes author links to the homepage
  • Changes author posts links to the site name / site URL

It’s pretty basic stuff but has lead to a 300% decrease in login attempts using a valid username on this site alone.

This plugin, is also available on Github Gist.

<?php
/**
 * Plugin Name: User Security
 * Description: Hides login errors, disables author archives (to hide usernames), changes author links to title => sitename / URL => homepage
 * Version:     1.0.0
 * Author:      James Morrison
 * Author URI:  https://james.morrison.me/
 **/


/**
 * Security Check
 *
 * @since 1.0.0
 **/

defined( 'ABSPATH' ) or die();


/**
 * Stop the redirect to "pretty permalinks" - i.e. ?author={ID} redirect to /author/{username}
 *
 * @since 1.0.0
 **/

add_filter( 'redirect_canonical', function( $redirect_url, $requested_url ) {

	if ( is_author() || ( ! empty( $_GET[ 'author' ] ) && preg_match( '|^[0-9]+$|', $_GET[ 'author' ] ) ) ) {
		return false;
	}

	return $redirect_url;

}, 1, 2 );


/**
 * Show a 404 template instead of author template
 *
 * @since 1.0.0
 **/

add_filter( 'template_include', function( $template ) {
	
	if ( is_author() || ( ! empty( $_GET[ 'author' ] ) && preg_match( '|^[0-9]+$|', $_GET[ 'author' ] ) ) ) {
		status_header(404);
		return get_404_template(); 
	}
	
	return $template;
	
}, 1, 1 );


/**
 * Change the author link to the homepage
 *
 * @since 1.0.0
 **/

add_filter( 'author_link', function( $link, $author_id, $author_nicename ) {

	return esc_url( home_url( '/' ) );

}, 1, 3 );


/**
 * Change the author posts link to generic text / homepage link
 *
 * @since 1.0.0
 **/

add_filter( 'the_author_posts_link', function( $link ) {

	return '<a title="' . get_bloginfo( 'name' ) . '" href="' . esc_url( home_url( '/' ) ) . '">' . get_bloginfo( 'name' ) . '</a>';

}, 1, 1 );


/**
 * Hide login errors; by default the error message give away whether the username was correct (and therefore the password was wrong)
 *
 * @since 1.0.0
 **/

add_filter( 'login_errors', function() {

	return 'You have entered an incorrect username or password.';

}, 1 );