How to Protect User Information in WordPress by Disabling Sensitive REST API Endpoints

Author: Gabriel

Published: 11/11/2025

If you’ve worked with WordPress before, you already know how powerful the REST API can be — but without proper configuration, it can also expose sensitive information. In this article, learn how default endpoints may reveal user data and how to easily control what should (and shouldn’t) be public.

How to Protect User Information in WordPress by Disabling Sensitive REST API Endpoints

If you’ve ever managed or developed large WordPress sites — especially news portals or multi-author blogs — you’ve probably noticed a high number of login attempts in the admin panel.
Security tools like Wordfence often log hundreds of brute-force attempts targeting user accounts that don’t even publish content. And when security measures aren’t in place, sometimes these attempts can succeed.

You might then wonder: how do attackers even discover valid usernames?

By default, WordPress includes a REST API that makes it easy for external applications to interact with the site. One of its default endpoints lists public information about users who have published at least one post.

It’s worth noting that WordPress itself does not expose sensitive information like emails or passwords — only basic public details such as usernames, IDs, and display names.
However, poorly configured plugins or themes can unintentionally expand what’s accessible through the REST API, exposing sensitive user data or metadata that should remain private. This makes it even more important to review what information each endpoint returns and ensure only the necessary data is available. The the email in the example bellow:

{
    "id": 20,
    "name": "Michael Scott",
    "url": "http://okuneva.info/hic-quae-sed-quo-consectetur",
    "description": "Aliquid dolorum et quidem harum amet nesciunt expedita. Non qui quod temporibus. Autem nihil ipsa delectus magnam animi illo. Commodi consequatur adipisci reiciendis vitae voluptas soluta.",
    "link": "http://wordpress.test/author/michael-scott/",
    "slug": "michael-scott",
    "avatar_urls": {
        "24": "https://secure.gravatar.com/avatar/88f577baee9a7d6b00c9b8bb69c97d0a7f5d2125b710b5387f958ea421c4c56f?s=24&d=mm&r=g",
        "48": "https://secure.gravatar.com/avatar/88f577baee9a7d6b00c9b8bb69c97d0a7f5d2125b710b5387f958ea421c4c56f?s=48&d=mm&r=g",
        "96": "https://secure.gravatar.com/avatar/88f577baee9a7d6b00c9b8bb69c97d0a7f5d2125b710b5387f958ea421c4c56f?s=96&d=mm&r=g"
    },
    "meta": [],
    "user_email": "michael.scott@dundermifflin.com",
    "_links": {
        "self": [
            {
                "href": "http://wordpress.test/wp-json/wp/v2/users/20",
                "targetHints": {
                    "allow": [
                        "GET"
                    ]
                }
            }
        ],
        "collection": [
            {
                "href": "http://wordpress.test/wp-json/wp/v2/users"
            }
        ]
    }
}

However, even this seemingly harmless data can be valuable in the wrong hands.
Attackers can use usernames as entry points for brute-force attacks, trying to guess passwords or exploit weak credentials. In large or high-traffic sites, this can quickly become a real security concern.

To be clear, this behavior is not a vulnerability — it’s a feature designed to support integrations with mobile apps, headless frontends, and other connected systems.
The WordPress REST API is an essential part of modern WordPress development, but it requires thoughtful configuration to ensure that it doesn’t unintentionally expose data that could be misused.

Fortunately, the fix is straightforward.
With just a small filter in your theme or plugin, you can control which REST API endpoints are visible and which should remain private — effectively limiting access to only what’s necessary for your project.

// Function to remove some REST API endpoints passed to and array of post types
if (! function_exists('remove_rest_api_endpoints_for_post_types')) :
    /**
     * Remove specified endpoints from the REST API.
     *
     * @param array $endpoints Array of endpoints to remove.
     * @return void
     */
    function remove_rest_api_endpoints_for_post_types($post_types = array(), $endpoints = array())
    {
        // Default endpoints to remove if not specified
        if (empty($endpoints)) {
            $endpoints = array(
                '/wp/v2/comments',
                '/wp/v2/users',
                '/wp/v2/taxonomies',
                '/wp/v2/terms',
                '/wp/v2/search'
            );
        }

        // Add endpoints for each post type
        foreach ($post_types as $post_type) {
            $endpoints[] = '/wp/v2/' . $post_type;
        }

        // Remove the specified endpoints
        foreach ($endpoints as $endpoint) {
            remove_action('rest_api_init', 'rest_api_default_filters', 10, 1);
            remove_action('rest_api_init', 'rest_api_meta_filters', 10, 1);

            // Remove the specific endpoint
            add_filter('rest_endpoints', function ($endpoints_list) use ($endpoint) {
                if (isset($endpoints_list[$endpoint])) {
                    unset($endpoints_list[$endpoint]);
                }
                return $endpoints_list;
            });
        }
    }
endif;
remove_rest_api_endpoints_for_post_types();

This simple step allows you to maintain all the benefits of the REST API while adding an extra layer of protection to your site. You keep integrations working smoothly while reducing the risk of unwanted data exposure.

The WordPress REST API is a powerful and legitimate feature, but even its default public data can become a weak point if left unmonitored.
Restricting or filtering specific endpoints is a simple yet effective way to strengthen your site’s security posture.

With just a few lines of code, you can keep the flexibility and performance benefits of the REST API — while ensuring your users’ information stays as private as it should be.

Tags:

REST APISecurityWordPress

More Posts

No more posts for now.