The WordPress REST API is a powerful feature, but it also introduces security considerations that don’t exist in traditional WordPress development. Every endpoint you expose is a potential attack surface. Without proper authentication, authorization, and input validation, your API can be exploited to access, modify, or delete data.
This guide covers how to secure your WordPress REST API endpoints, from choosing authentication methods to implementing rate limiting.
Authentication Methods
The WordPress REST API supports several authentication methods, each with different security characteristics. Application Passwords are the recommended method for external applications. They’re generated per-user, can be revoked independently of the user’s main password, and work with standard HTTP Basic Auth. Cookie authentication is suitable for same-origin requests where the user is already logged into WordPress. OAuth 1.0a is available for complex authorization scenarios with third-party applications.
Never accept API requests without authentication unless you have a specific reason. Every authenticated endpoint should verify that the request includes a valid token or cookie before processing. Log failed authentication attempts to detect brute force attacks.
Authorization: Who Can Do What
Authentication verifies who you are. Authorization verifies what you’re allowed to do. Every REST API endpoint should check that the authenticated user has the required capabilities before performing the requested action. Use current_user_can() with the appropriate capability for each operation.
Check capabilities at the endpoint level, not just at the route registration level. A user might have permission to list posts but not delete them. Each endpoint should enforce its own permission requirements, and the permission check should be specific to the resource being accessed, not just the route.
Rate Limiting
Rate limiting prevents a single client from making too many requests in a short period, protecting your API from abuse and denial-of-service attacks. Implement rate limiting at the server level using nginx or Apache configuration, or at the application level using a plugin or custom middleware.
Set different rate limits for authenticated and unauthenticated requests. Unauthenticated requests should be heavily limited — 10-20 requests per minute. Authenticated requests can have higher limits — 60-120 per minute. Return a 429 Too Many Requests status code with a Retry-After header when limits are exceeded.
Input Validation
All data received by your API endpoints must be validated and sanitized. The WordPress REST API provides built-in validation through the args parameter in register_rest_route(). Use type declarations, required flags, sanitize_callbacks, and validate_callbacks for every parameter.
Never trust the client to send valid data. Validate that IDs exist before using them. Verify that email addresses are properly formatted. Check that numeric parameters are within expected ranges. Strip unexpected HTML tags from text fields. Every piece of data should pass through at least one validation function before being used.
CSRF Protection
Cross-Site Request Forgery attacks trick browsers into making unauthorized requests to your API. WordPress nonces provide CSRF protection for cookie-authenticated requests. For requests using Application Passwords or OAuth, nonces aren’t needed because the authentication token itself acts as CSRF protection.
For custom endpoints that accept cookie authentication, verify the nonce using wp_verify_nonce() in the permission callback or the endpoint handler. Include the nonce in request headers using the X-WP-Nonce header, which the WordPress REST API client handles automatically.
The Bottom Line
REST API security follows the same principles as general WordPress security but with additional considerations for programmatic access. Authenticate every request, authorize every action, validate every input, limit request rates, and protect against CSRF. A well-secured API is safe to expose to the internet — a poorly secured one is a data breach waiting to happen.
