Security fix guide
MEDIUM

User Enumeration

WordPress is exposing your admin usernames via its REST API. Block it with one code snippet.

What is this?

WordPress has a built-in REST API — a set of URLs that apps and services use to communicate with your site. By default, one of those URLs is /wp-json/wp/v2/users. Anyone who visits that URL gets a neat JSON response listing your WordPress usernames, their display names, and their user IDs. No login required. Your scanner found that this endpoint is publicly accessible and returning usernames.

Why does it matter?

A brute-force attack needs two things: a username and a password. WordPress usernames are often not obvious (most sites have moved away from using "admin"). With user enumeration, an attacker skips the username-guessing step entirely — they already have your actual usernames. Combined with an accessible login page or XML-RPC, the bar for a successful attack drops significantly. This is why security frameworks rate this as a medium-severity finding.

How to fix it

These steps are written for shared hosting (cPanel, Plesk, or similar). If you have direct server access, see the SSH section below.

1

Log in to WordPress admin → Appearance → Theme File Editor. Or install the free "Code Snippets" plugin for a safer approach (changes survive theme updates).

2

Open functions.php (or create a new snippet) and add:

add_filter('rest_endpoints', function($endpoints) {
  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;
});

Note: This removes the users endpoint entirely. Legitimate features (WooCommerce, page builders) don't use it — it's safe to disable.

3

Save.

For developers / SSH access
1

Navigate to your active theme directory and edit functions.php:

nano /var/www/html/wp-content/themes/your-theme/functions.php
2

Add the same filter at the bottom:

add_filter('rest_endpoints', function($endpoints) {
  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;
});
3

Save (Ctrl+X, Y, Enter in nano).

How to verify the fix

Visit your-site.com/wp-json/wp/v2/users in a browser. If you get a 404 error or a "rest_no_route" response, it's working. Re-run your scan.

Re-run your scan to confirm this is resolved →

Related issues

← View full security checklist

Prefer to have this handled for you? Get this fixed — Medium ($89)