WordPress Security

Securing WordPress REST API v2: Complete Protection Guide

Learn how to secure the WordPress REST API v2 from unauthorized access, data leakage, and abuse while maintaining functionality.

S
Sarah Chen
9 min read
2,208 views
Comprehensive guide to securing WordPress REST API v2

The WordPress REST API v2 powers modern WordPress development, but also creates potential security vulnerabilities. This guide covers comprehensive API security strategies to protect your site while maintaining necessary functionality.

Understanding REST API Risks

The REST API exposes endpoints that can reveal sensitive information or allow unauthorized actions if not properly secured. Common risks include user enumeration, content exposure, and authentication bypass attempts.

Default Exposed Endpoints

Out of the box, WordPress exposes:

  • /wp-json/wp/v2/users - Lists all users with usernames
  • /wp-json/wp/v2/posts - Exposes all published content
  • /wp-json/wp/v2/pages - Lists all pages
  • /wp-json/wp/v2/comments - Shows comment data
  • /wp-json/wp/v2/media - Lists media library items

Disabling User Enumeration

User enumeration through the REST API is a significant security concern:

// Disable REST API user endpoint for non-logged users
add_filter('rest_endpoints', function($endpoints) {
    if (!is_user_logged_in()) {
        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[\d]+)']);
        }
    }
    return $endpoints;
});

Authentication Requirements

Require authentication for sensitive endpoints:

add_filter('rest_authentication_errors', function($result) {
    if (!empty($result)) {
        return $result;
    }

    if (!is_user_logged_in()) {
        return new WP_Error(
            'rest_not_logged_in',
            'You must be logged in to access this endpoint.',
            array('status' => 401)
        );
    }

    return $result;
});

Selective Endpoint Protection

Allow public access to specific endpoints while protecting others:

add_filter('rest_authentication_errors', function($result) {
    $public_routes = array(
        '/wp/v2/posts',
        '/wp/v2/pages',
        '/contact-form/v1/submit',
    );

    $current_route = $_SERVER['REQUEST_URI'];

    foreach ($public_routes as $route) {
        if (strpos($current_route, $route) !== false) {
            return $result;
        }
    }

    if (!is_user_logged_in()) {
        return new WP_Error('unauthorized', 'Authentication required', array('status' => 401));
    }

    return $result;
});

Rate Limiting API Requests

Implement rate limiting to prevent API abuse:

add_action('rest_api_init', function() {
    $ip = $_SERVER['REMOTE_ADDR'];
    $transient_key = 'api_rate_' . md5($ip);
    $requests = get_transient($transient_key) ?: 0;

    if ($requests > 100) { // 100 requests per minute
        wp_send_json_error(
            array('message' => 'Rate limit exceeded'),
            429
        );
    }

    set_transient($transient_key, $requests + 1, MINUTE_IN_SECONDS);
});

Validating and Sanitizing Input

Always validate API input data:

register_rest_route('custom/v1', '/submit', array(
    'methods' => 'POST',
    'callback' => 'handle_submission',
    'permission_callback' => '__return_true',
    'args' => array(
        'email' => array(
            'required' => true,
            'validate_callback' => function($param) {
                return is_email($param);
            },
            'sanitize_callback' => 'sanitize_email',
        ),
        'message' => array(
            'required' => true,
            'sanitize_callback' => 'sanitize_textarea_field',
        ),
    ),
));

CORS Configuration

Control which domains can access your API:

add_action('rest_api_init', function() {
    $allowed_origins = array(
        'https://yourdomain.com',
        'https://app.yourdomain.com',
    );

    $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';

    if (in_array($origin, $allowed_origins)) {
        header('Access-Control-Allow-Origin: ' . $origin);
        header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
        header('Access-Control-Allow-Credentials: true');
    }
}, 15);

Monitoring API Activity

Log REST API requests for security monitoring:

add_action('rest_api_init', function() {
    $log_entry = array(
        'time' => current_time('mysql'),
        'ip' => $_SERVER['REMOTE_ADDR'],
        'endpoint' => $_SERVER['REQUEST_URI'],
        'method' => $_SERVER['REQUEST_METHOD'],
        'user' => get_current_user_id(),
    );

    $logs = get_option('api_access_logs', array());
    array_unshift($logs, $log_entry);
    $logs = array_slice($logs, 0, 1000);
    update_option('api_access_logs', $logs);
}, 1);

Security Headers for API

Add security headers to API responses:

add_filter('rest_post_dispatch', function($response) {
    $response->header('X-Content-Type-Options', 'nosniff');
    $response->header('X-Frame-Options', 'DENY');
    $response->header('Cache-Control', 'no-store, no-cache, must-revalidate');
    return $response;
});

Conclusion

Securing the WordPress REST API requires layered protection—authentication, rate limiting, input validation, and monitoring. These measures protect your site while maintaining the functionality modern WordPress applications require.

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