The WordPress REST API is a powerful feature that enables developers to interact with a site’s data programmatically. While useful for headless setups, custom apps, and AJAX calls, it can also expose sensitive information if left unsecured.
By default, the REST API allows unauthenticated users to access a variety of endpoints, including details about users, posts, and taxonomies.
In this post, we will walk through several safe ways to secure your REST API without disrupting core functionality or plugin features that depend on it.
Why Secure the REST API?
Some REST API endpoints expose data that could be used by attackers for enumeration or reconnaissance. For example:
/wp-json/wp/v2/users– lists all registered users, including usernames and user IDs/wp-json/wp/v2/posts– public by default, exposing post content and metadata/?author=1– redirects to the author archive, revealing the username in the URL
Securing these endpoints helps prevent brute-force attacks, credential stuffing, phishing, and content scraping.
Do not disable the REST API entirely. WordPress core features like the block editor (Gutenberg), many plugins, and the WordPress admin itself depend on it. Disabling it will break your site. Instead, restrict access to specific endpoints or require authentication where needed.
Option 1: Restrict Access to Authenticated Users
You can require authentication for all REST API requests by adding the following code to your theme’s functions.php or a custom plugin:
add_filter('rest_authentication_errors', function($result) {
if (true === $result || is_wp_error($result)) {
return $result;
}
if (!is_user_logged_in()) {
return new WP_Error(
'rest_not_logged_in',
'You must be logged in to access the REST API.',
array('status' => 401)
);
}
return $result;
});Note the check for true === $result || is_wp_error($result) at the top. This ensures that if another authentication handler has already validated or rejected the request, we do not override it.
This approach blocks all unauthenticated REST API access, including public AJAX calls from the frontend. Use it only if your site does not rely on public API endpoints.
Option 2: Restrict Specific Endpoints Only
If you want to restrict only certain endpoints (like the users endpoint) while keeping the rest of the API intact, use this more targeted approach:
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;
});This removes both the users list endpoint and individual user endpoints. The block editor and other core features will continue to work normally since they do not depend on public access to user data.
Option 3: Block REST API for Non-Editors
You can limit REST API access based on user capabilities. For example, allow only editors and administrators:
add_filter('rest_authentication_errors', function($result) {
if (true === $result || is_wp_error($result)) {
return $result;
}
if (!is_user_logged_in()) {
return new WP_Error(
'rest_not_logged_in',
'Authentication required.',
array('status' => 401)
);
}
if (!current_user_can('edit_posts')) {
return new WP_Error(
'rest_forbidden',
'You do not have permission to access the REST API.',
array('status' => 403)
);
}
return $result;
});This checks the edit_posts capability, which subscribers and contributors do not have. Using capabilities rather than role names is the correct approach – current_user_can('subscriber') checks a role name, not a capability, and may not work reliably.
Option 4: Hide Sensitive User Data
Instead of disabling the users endpoint entirely, you can filter out sensitive fields from the response:
add_filter('rest_prepare_user', function($response, $user, $request) {
if (!current_user_can('list_users')) {
$data = $response->get_data();
unset($data['slug']);
unset($data['link']);
$response->set_data($data);
}
return $response;
}, 10, 3);This removes the slug (username) and link (author archive URL) from the response for users who do not have the list_users capability. The endpoint still works, but the most sensitive data is hidden.
Option 5: Use Application Passwords for External Access
Since WordPress 5.6, Application Passwords provide a built-in way to authenticate REST API requests from external tools, scripts, or mobile apps.
Each Application Password is tied to a specific user account, individually revocable, and cannot be used to log into wp-admin. This makes them safer than sharing your main password with third-party services.
To create one, go to Users > Your Profile and scroll to the “Application Passwords” section. Give it a descriptive name (e.g., “Deploy Script” or “Mobile App”) and save the generated password immediately – it will not be shown again.
External requests authenticate using HTTP Basic Auth with your WordPress username and the Application Password.
Option 6: Use a Security Plugin
Plugins like Wordfence, iThemes Security, or Disable REST API give you toggles to limit access without writing code. These tools offer granular control over what is accessible and to whom.
For most sites, a combination of code-level restrictions (Options 1-4) and a security plugin provides the strongest protection.
Don’t Forget Author Enumeration
Restricting the REST API users endpoint is important, but it is not the only way attackers discover usernames. WordPress also exposes usernames through author archive URLs.
Visiting /?author=1 redirects to /author/admin/, revealing the username. To block this, add the following to your theme’s functions.php:
add_action('template_redirect', function() {
if (is_author()) {
wp_redirect(home_url('/'), 301);
exit;
}
});This redirects all author archive requests to the homepage. If your site uses author archives for legitimate purposes, you can restrict this to non-logged-in users instead.
Testing Your API Security
After making changes, verify they work correctly. Test these URLs while logged out:
https://yoursite.com/wp-json/– see available routeshttps://yoursite.com/wp-json/wp/v2/users– check if user data is exposedhttps://yoursite.com/?author=1– check if author enumeration works
Use tools like Postman or your browser’s Developer Tools (Network tab) to inspect the response headers and body. Confirm that restricted endpoints return a 401 or 403 status code instead of user data.
Then log in and verify that the WordPress admin, block editor, and any plugins that use the REST API still function correctly.
FAQs
Common questions about securing the WordPress REST API:
Summary
The REST API is essential for modern WordPress, but securing it is equally important. Start by restricting the users endpoint (Option 2) since that is the most commonly exploited. Then evaluate whether you need broader restrictions based on your site’s needs.
For external integrations, use Application Passwords instead of sharing your main credentials. And do not forget to block author enumeration through /?author=N as well.
For a broader look at WordPress security, check out our guide on WordPress security hardening tips. You can also add security headers to further protect your site.


Thanks! it helped a lot!