How to Lock Down the WordPress REST API (2026 Guide)
Secure your WordPress REST API with authentication, rate limiting, endpoint control, and user enumeration prevention. Complete guide with VistoShield API Security.
Introduction: The WordPress REST API Is a Double-Edged Sword
The WordPress REST API, introduced in WordPress 4.7, transformed WordPress from a monolithic CMS into a headless content platform. It enables mobile applications, single-page frontends, third-party integrations, and inter-site communication. It is also one of the most significant attack surfaces on a modern WordPress installation.
By default, the REST API is open. Anyone can query /wp-json/wp/v2/users and retrieve a list of usernames. Anyone can enumerate posts, pages, categories, and media without authentication. For many sites, the REST API exposes data that was never intended to be public, and it does so through a structured, machine-readable interface that is trivial for automated tools to exploit.
This guide covers every aspect of securing the WordPress REST API — from disabling unnecessary endpoints to implementing robust authentication and rate limiting. We will also explain how VistoShield’s API Security plugin handles all of this through a single, configurable interface.
Understanding REST API Risks
Before implementing protections, you need to understand what you are protecting against. The REST API introduces several categories of risk that do not exist with the traditional WordPress admin interface.
User Enumeration
The most commonly exploited REST API vulnerability is user enumeration. By default, a simple unauthenticated GET request to /wp-json/wp/v2/users returns a JSON array containing every user’s username, display name, avatar URL, and user ID. This is functionally equivalent to handing an attacker a target list for brute-force attacks.
User enumeration is not limited to the /users endpoint. Author archives (/?author=1, /?author=2) and the /wp-json/wp/v2/posts?author=X endpoint also reveal usernames. The REST API makes this enumeration faster and more reliable because it returns structured JSON rather than HTML that requires parsing.
# Enumerate all users via REST API (unauthenticated)
curl -s https://example.com/wp-json/wp/v2/users | jq '.[].slug'
# Result: list of all usernames
"admin"
"editor-john"
"author-sarah"
Data Exposure
The REST API exposes more data than many site owners realize. Depending on your site’s configuration and installed plugins, the following may be publicly accessible:
- Posts and pages: Including draft titles (through certain query parameters), revision history, and custom fields
- Comments: Including commenter email addresses in some configurations
- Media: Including original upload filenames, EXIF metadata, and file paths
- Taxonomies: Categories, tags, and custom taxonomies
- Site settings: Site title, description, URL structure, timezone, and language
- Plugin/theme data: Many plugins register custom REST API endpoints that expose their data
Brute Force via API
Traditional brute-force protection focuses on the wp-login.php form. However, attackers increasingly target the REST API and XML-RPC for authentication attacks because these interfaces often bypass login rate limiting. The /wp-json/wp/v2/users/me endpoint with Basic Authentication headers is a common target. The XML-RPC wp.getUsersBlogs method allows testing credentials without triggering login form protections.
For a deeper look at brute-force prevention beyond the API, see our comprehensive brute force protection guide.
Abuse of Custom Endpoints
Plugins that register custom REST API endpoints frequently contain vulnerabilities. Contact form plugins, e-commerce platforms, membership systems, and analytics tools all create endpoints that may lack proper authorization checks, input validation, or rate limiting. A vulnerability in a single plugin endpoint can expose the entire site.
Authentication Methods for the REST API
Securing the REST API starts with controlling who can access it and how they authenticate. WordPress supports several authentication methods, each with different security characteristics.
Cookie Authentication (Default)
WordPress uses cookie-based authentication for requests originating from the admin dashboard. This works through the existing WordPress session and nonce system. Cookie authentication is appropriate for same-origin JavaScript requests (the block editor, for example) but is not suitable for external API consumers because it requires an active WordPress session.
Application Passwords
Introduced in WordPress 5.6, application passwords provide a built-in mechanism for external API authentication. Each application password is a unique credential tied to a specific user account. Key characteristics include:
- Generated through the user profile screen
- Transmitted via Basic Authentication headers
- Can be revoked individually without affecting the user’s main password
- Each application password can be named for identification
- Last-used timestamp for audit purposes
While application passwords are a significant improvement over sharing the user’s actual password, they have limitations: they grant the full permissions of the associated user account (no scope restriction), and Basic Authentication transmits credentials in base64 encoding (not encryption) on every request, making HTTPS mandatory.
OAuth 2.0
For production applications that need scoped access to the REST API, OAuth 2.0 is the recommended approach. OAuth provides token-based authentication with defined scopes (read-only, write, specific endpoints), token expiration and refresh, and a standard authorization flow that does not require sharing credentials. WordPress does not include OAuth support natively, but several plugins implement it.
API Key Authentication
For server-to-server communication where OAuth’s authorization flow is unnecessary, API key authentication provides a simpler alternative. An API key is a long random string included in request headers that identifies and authorizes the calling application. VistoShield’s API Security plugin provides an API key management system with the following features:
- Per-key permissions: Each API key can be restricted to specific endpoints (e.g., read-only access to posts)
- IP whitelisting: Keys can be restricted to specific IP addresses or ranges
- Expiration dates: Keys can be set to expire after a defined period
- Usage logging: Every request made with an API key is logged with timestamp, IP, endpoint, and response code
- Rate limits per key: Each key can have its own rate limit, independent of global limits
JWT (JSON Web Tokens)
JWT authentication is popular for headless WordPress setups where the frontend is a separate application (React, Vue, etc.). The user authenticates once with their credentials and receives a signed JWT that is included in subsequent requests. JWTs are stateless (no server-side session required), can include custom claims (user role, permissions), and have configurable expiration.
Rate Limiting Strategies
Rate limiting controls how many API requests a client can make within a given time window. Without rate limiting, the REST API is vulnerable to abuse including brute-force attacks, data scraping, denial of service, and resource exhaustion.
Global Rate Limits
A global rate limit applies to all API requests regardless of endpoint or authentication status. This is the first line of defense against automated abuse. Typical configurations include:
| Client Type | Requests per Minute | Requests per Hour | Rationale |
|---|---|---|---|
| Unauthenticated | 30 | 500 | Public consumers, search engines, legitimate bots |
| Authenticated (Application Password) | 120 | 5,000 | Trusted integrations with valid credentials |
| Authenticated (API Key) | Configurable per key | Configurable per key | Based on integration requirements |
| Admin cookie (dashboard) | No limit | No limit | Dashboard functionality should not be rate-limited |
Per-Endpoint Rate Limits
Some endpoints deserve stricter rate limits than the global default. Authentication endpoints (/wp-json/wp/v2/users/me), user enumeration endpoints (/wp-json/wp/v2/users), and search endpoints (/wp-json/wp/v2/search) should have significantly lower limits because they are the most commonly abused.
VistoShield’s API Security plugin allows you to set per-endpoint rate limits that override the global default. For example, you might allow 120 requests per minute globally but only 5 requests per minute to the /users endpoint for unauthenticated clients.
Rate Limit Headers
Legitimate API consumers need to know their rate limit status. VistoShield adds standard rate limit headers to every API response:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1711699260
Retry-After: 42
The Retry-After header is included when a client exceeds their rate limit, indicating how many seconds they should wait before retrying. This follows RFC 6585 and is recognized by well-behaved API clients and libraries.
Endpoint Whitelisting and Blacklisting
Not every REST API endpoint needs to be accessible. In fact, most WordPress sites only use a fraction of the available endpoints. Disabling or restricting access to unused endpoints reduces the attack surface significantly.
Whitelist Approach (Recommended for Most Sites)
A whitelist approach blocks all REST API access by default and only allows specific endpoints. This is the most secure configuration and is recommended for standard WordPress sites that do not use the REST API for external integrations:
- Allow:
/wp-json/wp/v2/(root, for discovery), block editor endpoints (Gutenberg requires them), contact form endpoints, any custom endpoints your site explicitly needs - Block everything else: Users, comments, media, settings, and all other default endpoints
Blacklist Approach (For Sites with External Integrations)
If your site uses the REST API for external consumers (headless frontend, mobile app, third-party integrations), a blacklist approach is more practical. Allow all endpoints by default but block specific high-risk ones:
- Block:
/wp-json/wp/v2/usersfor unauthenticated requests - Block:
/wp-json/wp/v2/settingsfor non-admin requests - Block: Any plugin endpoints that expose sensitive data
- Require authentication: All write operations (POST, PUT, DELETE)
Namespace-Level Control
REST API endpoints are organized by namespace (e.g., wp/v2, wc/v3 for WooCommerce, jetpack/v4). VistoShield allows you to enable or disable entire namespaces at once. This is useful for quickly disabling all endpoints registered by a specific plugin without having to identify each one individually.
Disabling XML-RPC
XML-RPC (xmlrpc.php) is the REST API’s predecessor and remains enabled by default in WordPress. It provides a significant attack surface and is rarely needed on modern WordPress sites.
Why XML-RPC Is a Security Risk
- Brute-force amplification: The
system.multicallmethod allows testing hundreds of passwords in a single HTTP request, bypassing per-request rate limiting - DDoS amplification: The
pingback.pingmethod can be used to amplify DDoS attacks by making your server send requests to a target - No rate limiting: XML-RPC has no built-in rate limiting mechanism
- Authentication bypass: Many login security plugins do not protect XML-RPC authentication, creating a backdoor for credential attacks
When You Can Safely Disable XML-RPC
You can disable XML-RPC if you do not use any of the following:
- Jetpack (requires XML-RPC for WordPress.com connection)
- The WordPress mobile app (older versions use XML-RPC; newer versions use the REST API)
- Pingbacks and trackbacks
- Remote publishing via third-party blog editors that use XML-RPC
For most WordPress sites, XML-RPC can and should be disabled entirely. VistoShield’s API Security plugin provides a one-click toggle to disable XML-RPC with proper HTTP 403 responses and an option to selectively allow specific XML-RPC methods if you need Jetpack compatibility.
CORS (Cross-Origin Resource Sharing) Management
CORS controls which domains can make JavaScript requests to your REST API. By default, WordPress allows CORS requests from any origin for GET requests, which means any website can query your public API endpoints from client-side JavaScript.
Restricting CORS Origins
For sites that use the REST API with a specific frontend (headless WordPress), CORS should be restricted to only the domains that need access:
# VistoShield CORS configuration example
Allowed origins: https://app.example.com, https://staging.example.com
Allowed methods: GET, POST, PUT, DELETE
Allowed headers: Authorization, Content-Type, X-WP-Nonce
Max age: 86400 (cache preflight for 24 hours)
Disabling CORS for Non-Headless Sites
If your WordPress site does not serve API data to external frontends, CORS can be disabled entirely. This prevents any cross-origin JavaScript request from accessing your REST API, limiting API access to server-side requests and same-origin dashboard requests. VistoShield provides a “Disable CORS” toggle that removes all CORS headers from REST API responses.
WooCommerce API Security
WooCommerce adds its own REST API namespace (wc/v3) with endpoints for products, orders, customers, coupons, and more. These endpoints handle sensitive commercial data and require additional security considerations.
WooCommerce-Specific Risks
- Customer data exposure: The
/wc/v3/customersendpoint exposes personal information including names, addresses, and email addresses - Order data: The
/wc/v3/ordersendpoint contains purchase history, billing details, and shipping addresses - Product manipulation: Unauthenticated or poorly authenticated write access could allow price manipulation, stock changes, or product deletion
- Coupon abuse: The
/wc/v3/couponsendpoint could be used to create unauthorized discount codes
Securing WooCommerce Endpoints
VistoShield’s API Security plugin includes WooCommerce-specific protections:
- Authentication requirement for all WooCommerce endpoints: No unauthenticated access to any
wc/v3endpoint - Read/write separation: Allow read-only access for storefront applications while requiring elevated authentication for write operations
- Customer data filtering: Remove sensitive fields (email, phone, address) from customer API responses for non-admin consumers
- Order webhook security: Verify webhook signatures and restrict delivery to whitelisted URLs
- Enhanced rate limiting: Stricter rate limits for WooCommerce endpoints to prevent inventory scraping and price monitoring abuse
User Enumeration Prevention
User enumeration is one of the most critical REST API vulnerabilities because it directly enables credential attacks. VistoShield implements multiple layers of user enumeration prevention.
REST API User Endpoint
The most obvious vector is the /wp-json/wp/v2/users endpoint. VistoShield can restrict this endpoint to authenticated users only, require admin privileges for user listing, or disable it entirely. Even when the endpoint is accessible, VistoShield can filter the response to remove sensitive fields like the user slug (which is typically the login username).
Author Archive Enumeration
WordPress author archives (/?author=1) redirect to /author/username/, revealing the username in the URL. The /wp-json/wp/v2/posts?author=X endpoint reveals usernames through the author field in post responses. VistoShield blocks both vectors by intercepting author parameter queries and removing author identifying information from unauthenticated API responses.
oEmbed Enumeration
The oEmbed discovery endpoint (/wp-json/oembed/1.0/embed) can also reveal author information. VistoShield filters oEmbed responses to remove author data for unauthenticated requests.
Implementation with VistoShield API Security
VistoShield’s API Security plugin consolidates all of these protections into a single management interface. Here is how to implement a comprehensive REST API security configuration.
Quick Setup (5 Minutes)
- Install and activate the API Security plugin from the plugin page or WordPress repository.
- Select a security profile: Choose “Standard” (most sites), “Headless” (decoupled frontends), or “Locked Down” (maximum restriction).
- Disable XML-RPC: Toggle on unless you specifically need it for Jetpack or remote publishing.
- Enable user enumeration prevention: Toggle on (this should be enabled on every site).
- Configure rate limits: Start with the defaults (30/min unauthenticated, 120/min authenticated) and adjust based on your site’s traffic patterns.
Security Profiles Explained
| Profile | REST API Access | XML-RPC | CORS | User Enum | Rate Limits |
|---|---|---|---|---|---|
| Standard | Whitelist (Gutenberg + essential) | Disabled | Disabled | Blocked | Moderate |
| Headless | All endpoints (auth required for write) | Disabled | Configured origins | Blocked | High |
| Locked Down | Blocked for unauthenticated | Disabled | Disabled | Blocked | Strict |
| WooCommerce | Store endpoints + Gutenberg | Disabled | Store domain only | Blocked | WooCommerce-optimized |
Advanced Configuration
For sites with specific requirements, every setting is individually configurable:
- Endpoint rules: Create allow/deny rules for specific endpoints with optional authentication requirements
- IP-based rules: Allow unrestricted access from specific IPs (your application server, for example) while restricting all other traffic
- Custom rate limit tiers: Create named rate limit profiles and assign them to specific endpoints or API keys
- Response filtering: Configure which fields are included in API responses for different authentication levels
- Logging: Control the level of API request logging (all requests, errors only, or disabled)
Monitoring and Alerting
Securing the REST API is not a set-and-forget operation. Ongoing monitoring is essential to detect new threats, identify misconfigured integrations, and respond to attacks in progress.
API Request Dashboard
VistoShield’s API Security plugin provides a dashboard showing real-time and historical API activity:
- Total requests per hour/day/week with trend indicators
- Top endpoints by request volume
- Rate limit violations by IP and endpoint
- Authentication failures (invalid keys, expired tokens)
- Blocked requests by reason (rate limit, blacklisted endpoint, user enumeration attempt)
Email Alerts
Configure email alerts for security-significant events:
- Repeated authentication failures from a single IP (possible brute-force attack)
- Rate limit violations exceeding a threshold (possible automated scraping)
- Requests to disabled endpoints (possible reconnaissance)
- New API key usage from an unexpected IP address
Common Pitfalls to Avoid
When securing the REST API, several common mistakes can break site functionality or create a false sense of security.
Do Not Disable the REST API Entirely
The WordPress block editor (Gutenberg) depends on the REST API. Disabling it completely will break the editor, the site health screen, and numerous other admin features. Instead, use endpoint-level controls to restrict access to only what is needed.
Do Not Rely on Security Through Obscurity
Changing the REST API base URL (from /wp-json/ to something else) is sometimes suggested as a security measure. This provides negligible benefit because the URL is easily discoverable through the HTML <link> tag in the page source, the Link HTTP header, and automated scanning tools. Focus on authentication and access control rather than hiding endpoints.
Test After Configuration
After implementing REST API restrictions, thoroughly test your site. Verify that the block editor works correctly, that any third-party integrations still function, that contact forms submit successfully, and that WooCommerce checkout (if applicable) completes without errors. VistoShield includes an API Health Check tool that tests critical endpoints and reports any that are unexpectedly blocked.
Integration with the VistoShield Ecosystem
API Security works best when combined with other VistoShield plugins:
- Firewall & WAF: The WAF inspects API request payloads for SQL injection, XSS, and other attack patterns. API Security handles access control and rate limiting; the WAF handles content inspection. Together, they provide comprehensive API protection. See our WAF guide for details.
- Bot Detector: Identifies and categorizes API consumers as legitimate bots (search engines, uptime monitors), malicious bots (scrapers, credential stuffers), or humans. Bot classification can influence rate limits and access rules.
- Activity Log: All API security events (rate limit violations, blocked requests, authentication failures) are recorded in the activity log for forensic analysis.
- Login Security: Shares IP reputation data with API Security so that IPs flagged for login abuse are automatically subject to stricter API rate limits.
Pricing and Availability
The VistoShield API Security plugin is free and open source under the GPLv2 license. The free version includes endpoint control, XML-RPC disable, user enumeration prevention, and basic rate limiting. The Pro version adds per-key rate limits, WooCommerce-specific protections, API key management, CORS configuration, and the request monitoring dashboard.
- Free: Endpoint whitelisting/blacklisting, XML-RPC disable, user enumeration prevention, global rate limiting
- Single Plugin Pro: €19/site/year — adds API key management, per-endpoint rate limits, WooCommerce protection, monitoring dashboard
- Pro Bundle: €49/site/year — all 9 VistoShield plugins with Pro features
- Agency: €149/year for 25 sites — centralized API security management across your portfolio
For full pricing details, visit the pricing page.
Key Takeaways
- The WordPress REST API is open by default. User enumeration, data exposure, and brute-force attacks via API are real and common threats that every WordPress site faces.
- Authentication is the foundation. Every non-public endpoint should require authentication. Application passwords, API keys, and OAuth each serve different use cases.
- Rate limiting is essential. Without rate limits, the REST API is an open invitation for automated abuse. Differentiate limits by authentication status and endpoint sensitivity.
- Disable what you do not use. XML-RPC should be disabled on most sites. Unused REST API endpoints should be blocked. The smaller your API surface, the smaller your attack surface.
- User enumeration must be prevented. Block the
/usersendpoint, author archive enumeration, and oEmbed author disclosure. This directly reduces the effectiveness of credential attacks. - WooCommerce sites need additional protections. Customer data, order history, and product information require stricter access controls than standard WordPress content.
- VistoShield’s API Security plugin provides all of this in a single, free, GPLv2-licensed plugin with optional Pro features for advanced requirements.
- For setup instructions, visit the API Security documentation.