Security PHP Intermediate

Disable User Enumeration via REST API and Author Archives

Last updated: May 6, 2026

WordPress makes it easy, by design, to find usernames. The REST API exposes a public /wp-json/wp/v2/users endpoint that returns a list of all registered authors including their display names and slugs. The URL pattern /?author=1 redirects to the author archive for user ID 1, typically your first admin account, revealing their username in the URL. Attackers use both of these methods in automated reconnaissance before launching credential brute-force attacks, because knowing the exact username cuts the work in half.

The Code

This snippet addresses both enumeration paths. Add it to your functions.php or a site-specific plugin.

Blocking the REST API Endpoint

The rest_endpoints filter receives an array of all registered REST API routes. The snippet removes the /wp/v2/users and /wp/v2/users/(?P<id>[d]+) routes when the current request is not from a logged-in user. Authenticated requests, from the block editor, REST API clients using application passwords, or your own admin tools, are unaffected. Only unauthenticated public access is blocked.

This approach is preferable to disabling the REST API entirely, which breaks the block editor, WooCommerce, and a large number of modern plugins that depend on REST API access.

Blocking Author Archive Enumeration

The second block hooks into init and checks for a numeric author query parameter in the request. If found and the current user doesn’t have the list_users capability (which requires administrator or editor role), the request is redirected to the homepage with a 301. This prevents the /?author=1 redirect from completing, which means the username never appears in the URL.

The ! is_admin() check ensures this doesn’t interfere with admin-side requests where author parameters are used legitimately.

Testing the Fix

After adding this snippet, open an incognito window and visit yourdomain.com/wp-json/wp/v2/users. You should receive a 404 response rather than a JSON list of users. Also test yourdomain.com/?author=1, it should redirect to your homepage rather than to an author archive URL containing a username.

Tools like WPScan use both of these vectors by default in their user enumeration module. Running a scan against your own site before and after applying this snippet is a useful way to confirm it’s working as expected.

Display Names vs Usernames

One important note: this snippet blocks enumeration of login usernames through automated means, but it doesn’t prevent users’ display names from appearing in post bylines, comment sections, or author archive page titles. If a user’s display name matches their login username, which is WordPress’s default, their login credential is still effectively public. Encourage all authors to set a display name different from their login username under Users → Profile → Display name publicly as.

functions.php
// Block unauthenticated access to the REST API users endpoint
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;
} );

// Prevent user enumeration via ?author=N URL redirect
add_action( 'init', function() {
    if (
        ! is_admin() &&
        isset( $_REQUEST['author'] ) &&
        ! current_user_can( 'list_users' )
    ) {
        wp_redirect( home_url( '/' ), 301 );
        exit;
    }
} );

Built by Nahnu Plugins

Need something more powerful than a snippet?

Our commercial plugins go further, built for serious WordPress sites with full support, updates, and documentation included.

Browse All Plugins →

This website uses cookies to enhance your browsing experience and ensure the site functions properly. By continuing to use this site, you acknowledge and accept our use of cookies.

Accept All Accept Required Only