Stop User Enumeration/Phishing in WordPress

This tutorial explains how to block user-enumeration scans in WordPress. As explained in greater depth here, user enumeration happens when some malicious script scans a WordPress site for user data by requesting numerical user IDs. For example, requests for author=1 through some number, say, author=1000, may reveal the usernames for all associated users. With a simple enumeration script, an attacker can scan your site and obtain a list of login names in a matter of seconds.

How it works

When scanning a site for user IDs, disclosure of user data happens in two ways. First, for permalink-enabled sites, requests for ?author=n (where n equals any integer) are redirected to the permalink version of the URL for that user, which by default includes the author’s login username. So for example, on a permalink-enabled site, the following URI requests:


..automatically are redirected by WordPress to their “pretty permalink” counterparts:


..of course, the actual usernames will vary depending on your site, but you get the idea.

The second reason that user enumeration works to reveal user data is that theme templates typically display the author name on author-archive pages, in post meta information, and possibly in other locations, depending on the theme.

For more details on user enumeration, check out my article on blocking user ID phishing requests over at htaccessbook.com.

Should you be worried?

If you are sure that all of your users are using strong passwords that are updated regularly, then there is nothing to worry about. This tutorial is aimed at sites with multiple authors who may not be “password savvy”. If an author is being lazy with their passwords, then user-enumeration could definitely put your site at risk. Equipped with a known username, a perpetrator quickly may gain access using a simple brute-force attack.

So to be safe, check out the following techniques to protect your site against user-enumeration and brute-force attacks. They take only a minute to implement, and will serve to harden your WordPress-powered site with additional layers of security.

Step 1: Disable the scans

The first thing we want to do is block the malicious enumeration scanning. This can be done in one of two ways:

  • Add a code snippet to your theme’s functions.php file
  • Add a code snippet to your site’s root .htaccess file

Let’s check out each of these methods..

Block user-enumeration via functions.php

To block user-enumeration via functions.php, add the following code to your theme’s functions file:

// block WP enum scans
if (!is_admin()) {
	// default URL format
	if (preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING'])) die();
	add_filter('redirect_canonical', 'shapeSpace_check_enum', 10, 2);
function shapeSpace_check_enum($redirect, $request) {
	// permalink URL format
	if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) die();
	else return $redirect;

No editing is required for this to work, just copy/paste and done. Here’s how it works:

  1. Check if the request is for any page in the WP Admin Area
  2. Block the request if it’s for a query-string author archive

That’s the basic gist of it. Hit me up in the comments section for more specifics on what this code is doing, how it works, etc.

Block User Enumeration via .htaccess

If you would rather block requests at the server level, you can add the following slice of .htaccess to your site’s root .htaccess file:

# Block User ID Phishing Requests
<IfModule mod_rewrite.c>
	RewriteCond %{QUERY_STRING} ^author=([0-9]*)
	RewriteRule .* http://example.com/? [L,R=302]

The only edit that’s required is the domain/URI, http://example.com/, which you should change to match your own. For more information about this technique, check out my tutorial on blocking user-id phishing.FYI: You can also stop user enumeration with BBQ Pro Firewall »

Step 2:

At this point, we’ve added a code snippet (in either functions or .htaccess) that will block those nasty user-enumeration scans. The second part of the equation is to make sure that your theme does not disclose the login username of any authors or users. Unfortunately, there is no quick, one-step solution for this step, as it requires careful examination of your theme. Here are some things to check:

  • Author name displayed for each post
  • Author name displayed for author-archive views
  • Author name displayed anywhere else on the front-end

If your theme displays author names anywhere (as most themes do), there are few ways to prevent username disclosure:

  • Change all user Display Names to anything other than the login name
  • Make sure any author/user template tags are not displaying the login name
  • Remove any template tags that display author/user login names
  • Disable author archives entirely (if not needed)

Of course, this is a general guide that may not be applicable to every theme on the face of the planet (there’s only like a billion of them). But it should be enough to give you the idea and help you implement the best possible solution for your site.

Comments are closed.