Skip to content
All guides

WordPress User Enumeration: What It Is and How to Stop It

For developers 8 min readChecked October 26, 2026

A username is half of a login. WordPress user enumeration is the habit WordPress has of giving usernames away to anyone who asks, through author pages, the REST API, sitemaps and login errors. This guide shows how to test your own site, why it matters and how to close each leak.

What user enumeration is

Enumeration means collecting a list of valid usernames from a site. An attacker does not need to guess usernames if the site hands them over, and with a username in hand, guessing a password is half as hard.

Many of the leaks are features, not bugs. WordPress shows author names so readers can find an author's posts. The problem is that the same features can reveal the login name behind the account.

Why it matters

Knowing that an account called editor-jane exists, and that it is an administrator, lets an attacker aim password guessing, phishing and credential stuffing at it. A bot that already has your administrator's username also gets past defences that only block the username admin.

Blocking enumeration does not make a weak password strong. It simply removes a free hint.

The ways WordPress leaks usernames

There are four common leaks.

  • Author archives. Visiting /?author=1 redirects to /author/username/, which shows the author slug, and by default that slug is the login name.
  • The REST API. /wp-json/wp/v2/users lists users who have published posts, with their names and slugs.
  • User sitemaps. Since WordPress 5.5 the built-in sitemap includes a users page at /wp-sitemap-users-1.xml.
  • Login errors. Different messages for a wrong username and a wrong password reveal whether an account exists. Password reset forms can leak the same way.
  • Embeds and feeds. oEmbed data and some feeds include author names and links.

Test your own site

Check each leak with a request from a signed-out browser or a command line. If any of them returns a real username, you have found a leak.

Quick checks
# Author redirect: look for a Location header containing /author/
curl -sI "https://yoursite.com/?author=1"

# REST API user list: a JSON list means it is open
curl -s "https://yoursite.com/wp-json/wp/v2/users"

# User sitemap
curl -sI "https://yoursite.com/wp-sitemap-users-1.xml"

Stop WordPress user enumeration in code

You can close the REST API and sitemap leaks with a few lines in a small plugin or must-use plugin. Only change what signed-out visitors see, so the block editor and other admin tools keep working.

Check that your theme or an app does not rely on the public users endpoint before you remove it.

PHP: hide the users endpoints and sitemap from visitors who are not signed in
add_filter( 'rest_endpoints', function ( $endpoints ) {
	if ( ! is_user_logged_in() ) {
		unset( $endpoints['/wp/v2/users'] );
		unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
	}
	return $endpoints;
} );

add_filter( 'wp_sitemaps_add_provider', function ( $provider, $name ) {
	return ( 'users' === $name ) ? false : $provider;
}, 10, 2 );

Block the author redirect

The ?author=1 redirect can be refused at the server. The rule below sends signed-out guessers home. It leaves the admin area alone, because the WordPress admin uses an author parameter for its own filters.

If your site uses real author archive pages, you will need to keep them and instead make sure the archive address (the slug) is not the login name.

Apache .htaccess (above the WordPress block)
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} !^/wp-admin
  RewriteCond %{QUERY_STRING} (^|&)author=[0-9]+ [NC]
  RewriteRule ^ /? [R=301,L]
</IfModule>

Make login errors vague

A message such as 'Unknown username' tells an attacker that the account does not exist, while 'The password you entered is incorrect' confirms that it does. Show one message for both, for example that the username or password is wrong. Do the same on the password reset form: say that an email will be sent if the account exists.

PHP: one vague sign-in error
add_filter( 'login_errors', function () {
	return 'The username or password is incorrect.';
} );

Go further with display names and slugs

Even with every leak closed, a login name that is also the public display name or the author slug is still public. Give every user a display name that differs from their login, and avoid logins that match an email address or the name shown on posts.

Pair all of this with two-factor sign-in and lockouts, because a clever attacker can still find usernames from other places, such as your contact page or a data breach.

WordPress user enumeration: questions

Is user enumeration a vulnerability in WordPress?

WordPress treats most of it as expected behaviour, because author pages and the REST API are features. It is still worth closing, because the usernames help attackers.

Will blocking enumeration break my site?

Not for visitors, but it can break themes or apps that read the public users endpoint, and author archives on sites with plain permalinks. Test after you change it.

Are display names the same as usernames?

No. The display name is shown publicly, while the login name is used to sign in. Make sure they are different, and check the author slug as well.

Does the REST API need to be disabled completely?

No. Only hide the users endpoints from signed-out visitors. Disabling the whole REST API breaks the block editor, forms and many plugins.

How can I check if my site leaks usernames?

Run the three requests in this guide, or use the free security check at /tools/security-check, which looks for a user list and other common leaks.

Protect your WordPress site free

Most of this guide is one switch in Stack Guard.