Try this on your WordPress site right now: add ?author=1 to your homepage URL. Like this: yoursite.com/?author=1. Press Enter.
If you haven’t taken steps to block this, WordPress will redirect you to yoursite.com/author/admin/ (or whatever your admin username is). You just discovered the admin username in 2 seconds.
This is called author enumeration, and every bot on the internet knows this trick. It’s the first step in a brute force attack: find the username, then start guessing passwords.
What is author enumeration?
WordPress assigns a numeric ID to every user, starting with 1 for the first (usually admin) account. When you request ?author=1, WordPress looks up user ID 1 and redirects to their author archive page. The URL of that page contains the username slug.
Attackers don’t stop at ?author=1. They cycle through ?author=2, ?author=3, and so on, mapping every user account on your site in seconds. Automated tools do this at machine speed.
But the URL parameter isn’t the only leak. WordPress also exposes usernames through:
- REST API —
yoursite.com/wp-json/wp/v2/usersreturns a JSON list of all users with their slugs - Author archives — direct URLs like
/author/username/ - oEmbed endpoints — the
author_urlfield in oEmbed responses - RSS feeds — the
field in feed entries - Login error messages — “The password you entered for username X is incorrect”
That’s five different ways your WordPress site broadcasts user information by default.
Why should you care?
It’s step one of every brute force attack. Knowing the username cuts the attacker’s work in half. Instead of guessing both username and password, they only need to guess the password. With leaked password databases containing billions of entries, a known username dramatically increases the chance of a successful attack.
The REST API makes it trivially easy. A single API request to /wp-json/wp/v2/users returns every public user’s name, slug, description, and avatar URL in clean JSON. No authentication needed. It’s like publishing your employee directory with login credentials hints.
It confirms WordPress is installed. The ?author=1 redirect pattern is a fingerprint that confirms WordPress is running and active. Combined with the version number, this gives attackers a complete reconnaissance picture.
The quick fix
Block the ?author= parameter:
// Block author enumeration via URL parameter
add_action( 'init', function() {
if ( ! is_admin() && isset( $_GET['author'] ) ) {
wp_redirect( home_url(), 301 );
exit;
}
});
Block the REST API users endpoint (for non-authenticated requests):
// Block public access to REST API users endpoint
add_filter( 'rest_endpoints', function( $endpoints ) {
if ( ! is_user_logged_in() ) {
if ( isset( $endpoints['/wp/v2/users'] ) ) {
unset( $endpoints['/wp/v2/users'] );
}
if ( isset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ) ) {
unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
}
}
return $endpoints;
});
Together, these close the two most common enumeration vectors. For complete protection, also consider disabling author archives and hiding login error messages (separate OvKit features).
The one-click solution
OvKit includes Block Author Enumeration under Features → Security. One toggle blocks the ?author= parameter redirect, restricts the REST API users endpoint for non-authenticated visitors, and handles edge cases like feed author disclosure. Logged-in admins retain full access.
What happens after you fix this?
?author=1returns a 301 redirect to the homepage instead of revealing the username- REST API users endpoint returns 403 for non-authenticated requests
- Brute force bots lose their first reconnaissance step — they don’t know which usernames to target
- Your site looks less like a WordPress target — one fewer default behavior pattern
FAQ
Will this break my author archive pages?
The code above blocks the ?author=1 query parameter redirect, not the author archive itself. Direct visits to /author/username/ still work if you want author archives visible. For complete username hiding, you’d also want to disable author archives or change the author slug to something other than the username.
Does blocking the REST API users endpoint break Gutenberg or plugins?
No, because the block only applies to non-authenticated requests. When you’re logged into WordPress, the REST API users endpoint works normally. Gutenberg, WooCommerce, and admin-facing plugins that use the REST API are unaffected.
What about usernames in my blog post bylines?
The display name shown on posts (like “Tomas” or “Admin”) can be different from the login username. Go to Users → Your Profile and change “Display name publicly as” to your first name or a nickname — never your login username.
Related reads: