WordPress Security

Securing the WordPress REST API: Complete Guide

Learn how to secure the WordPress REST API against unauthorized access and data exposure. Implement authentication, rate limiting, and endpoint protection.

S
Sarah Chen
7 min read
1,218 views
WordPress REST API security configuration and protection

The WordPress REST API provides programmatic access to your site's data. While powerful for development, it can expose sensitive information if not properly secured. Understanding REST API security protects your site from data leaks and unauthorized access.

Understanding REST API Exposure

By default, the REST API exposes various endpoints:

  • /wp-json/wp/v2/users - User information
  • /wp-json/wp/v2/posts - All posts
  • /wp-json/wp/v2/pages - All pages
  • /wp-json/wp/v2/comments - Comments
  • /wp-json/wp/v2/media - Media files

Information Disclosure Risks

The users endpoint reveals usernames, which attackers use for brute force attacks. Other endpoints may expose unpublished content or sensitive metadata.

Authentication Methods

Cookie Authentication

Used for logged-in users making requests from the browser:

// Nonce verification for cookie auth
wp_localize_script('my-script', 'wpApiSettings', array(
    'root' => esc_url_raw(rest_url()),
    'nonce' => wp_create_nonce('wp_rest')
));

Application Passwords

WordPress 5.6+ supports application passwords for external API access:

  • Generate unique passwords per application
  • Revoke individual passwords without changing main password
  • Track last used date for each password

JWT Authentication

Popular for headless WordPress implementations:

  • Stateless authentication
  • Token expiration for security
  • Refresh token rotation

Restricting Public Access

Require Authentication for All Requests

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)
        );
    }

    return $result;
});

Disable User Enumeration

// Remove users endpoint
add_filter('rest_endpoints', function($endpoints) {
    if (isset($endpoints['/wp/v2/users'])) {
        unset($endpoints['/wp/v2/users']);
    }
    if (isset($endpoints['/wp/v2/users/(?P[\d]+)'])) {
        unset($endpoints['/wp/v2/users/(?P[\d]+)']);
    }
    return $endpoints;
});

Custom Endpoint Security

Permission Callbacks

register_rest_route('myplugin/v1', '/data', array(
    'methods' => 'GET',
    'callback' => 'get_my_data',
    'permission_callback' => function() {
        return current_user_can('edit_posts');
    }
));

Input Validation

register_rest_route('myplugin/v1', '/item/(?Pd+)', array(
    'methods' => 'GET',
    'callback' => 'get_item',
    'args' => array(
        'id' => array(
            'validate_callback' => function($param) {
                return is_numeric($param);
            },
            'sanitize_callback' => 'absint'
        )
    ),
    'permission_callback' => '__return_true'
));

Rate Limiting

Prevent API abuse with request limiting:

Implementation Example

add_filter('rest_pre_dispatch', function($result, $server, $request) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $transient_key = 'rest_limit_' . md5($ip);
    $requests = get_transient($transient_key) ?: 0;

    if ($requests > 100) { // 100 requests per minute
        return new WP_Error(
            'rate_limit_exceeded',
            'Too many requests',
            array('status' => 429)
        );
    }

    set_transient($transient_key, $requests + 1, 60);
    return $result;
}, 10, 3);

CORS Configuration

Control which domains can access your API:

add_action('rest_api_init', function() {
    remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
    add_filter('rest_pre_serve_request', function($value) {
        $allowed_origins = array(
            'https://myapp.com',
            'https://admin.myapp.com'
        );

        $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
        if (in_array($origin, $allowed_origins)) {
            header('Access-Control-Allow-Origin: ' . $origin);
            header('Access-Control-Allow-Credentials: true');
        }
        return $value;
    });
});

Logging API Requests

Monitor API usage for security analysis:

  • Log authentication failures
  • Track unusual request patterns
  • Monitor rate limit triggers
  • Record endpoint access statistics

Sensitive Data Protection

  • Never expose passwords or hashes
  • Filter sensitive user meta
  • Limit exposed post metadata
  • Protect private post content

Conclusion

REST API security requires authentication, authorization, rate limiting, and careful endpoint management. Implement these measures to protect your WordPress data from unauthorized API access.

Share:
S
Written by Sarah Chen

WP Folder Shield Team

Related Articles

SEO Spam Injection: How to Detect Hidden Links and Malicious Redirects
SEO Spam Injection: How to Detect Hidden Links and Malicious Redirects

Learn how hackers inject hidden links and malicious redirects into WordPress sites to steal your...

January 18, 2026
Understanding WordPress Malware Signatures and Detection Patterns
Understanding WordPress Malware Signatures and Detection Patterns

Learn how malware scanners detect threats using signatures and patterns. Understand the technology...

January 15, 2026
Country Blocking for WooCommerce: Protect Your Online Store
Country Blocking for WooCommerce: Protect Your Online Store

Learn how to implement country blocking for WooCommerce stores. Prevent fraud, reduce chargebacks...

January 10, 2026

Ready to Secure Your WordPress Site?

Get complete protection with WP Folder Shield.

Get Started