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.
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.
Written by Sarah Chen
WP Folder Shield Team