WP Tango

How to Secure WordPress XMLRPC Access Safely

Secure WordPress XMLRPC access without breaking Jetpack, mobile publishing, or integrations. Use deny rules, IP allowlists, rate limits, and verification checks.

October 11, 2026
How to Secure WordPress XMLRPC Access Safely

Most sites should secure WordPress XMLRPC access by blocking `xmlrpc.php` entirely unless a known service genuinely needs it. XML-RPC is a legacy remote procedure endpoint that remains a frequent target for password guessing and pingback abuse. Start with a default-deny rule at the web server or firewall, then create narrow exceptions for trusted IP addresses or required services. Do not disable it blindly if your publishing workflow, Jetpack features, or a third-party integration depends on it.

Why XML-RPC is still a WordPress attack surface

XML-RPC lets external clients send commands to WordPress over HTTP. It was built for remote publishing, mobile applications, trackbacks, pingbacks, and tools that need to interact with a site without loading the normal WordPress admin interface.

The endpoint is simple: `/xmlrpc.php`. That simplicity is also the problem. Attackers can repeatedly hit it with `POST` requests, probe for enabled methods, abuse pingbacks to reflect traffic toward another target, or use the `system.multicall` method to attempt many password combinations in one request.

A normal login attack against `wp-login.php` is easier to observe and rate-limit because each attempt usually produces a separate request. XML-RPC multicall requests can package many attempts together. If a host, CDN, or security plugin only counts requests rather than authentication attempts, its protection can be weaker than it appears.

This does not mean every site with XML-RPC enabled is compromised. It means leaving an unused remote-access endpoint exposed is poor operational hygiene. The correct configuration depends on whether anything actually uses it.

First, determine whether XML-RPC is needed

Before blocking the endpoint, identify what may break. Common legitimate users include the WordPress mobile app, desktop publishing clients, older automation tools, and certain Jetpack-connected features. Some older integrations still use XML-RPC even when newer alternatives exist.

For many business sites, especially WooCommerce stores managed through the dashboard, XML-RPC has no active purpose. WooCommerce APIs generally use the REST API, not XML-RPC. Modern WordPress integrations increasingly do the same.

Check your server access logs for requests to `xmlrpc.php` over at least a few weeks. You are looking for more than random internet noise. Record the source IP, request frequency, user agent, response code, and request size. Legitimate traffic tends to be predictable and tied to a known tool or provider. Attack traffic is often high-volume, distributed, or paired with repeated 200 responses and unusual POST payloads.

Do not treat a 200 response as proof of a successful login. WordPress can return an XML response with an application-level error while the HTTP status remains 200. Inspect the request pattern and, where appropriate, the response body.

A quick command-line check

If you have shell access, this checks whether the endpoint is responding:

bash
curl -i -X POST https://example.com/xmlrpc.php \ -H "Content-Type: text/xml" \ --data 'system.listMethods'

A live XML-RPC endpoint typically returns XML listing methods or an XML fault. A `403 Forbidden`, `404 Not Found`, or a connection rejection may indicate that it is already blocked. Run this from a location that matches the client you expect to use. An IP allowlist can make a test from your office succeed while a third-party service remains blocked.

The best way to secure WordPress XMLRPC access

Use the narrowest control that preserves required functionality. Web server and firewall controls are preferable because they reject unwanted traffic before PHP starts, protecting PHP workers and reducing wasted CPU time. This matters on high-traffic WordPress and WooCommerce sites, where a burst of expensive dynamic requests can compete with cart, checkout, and logged-in sessions.

If nothing needs XML-RPC, block it at the web server

For NGINX, deny the endpoint before it reaches PHP:

nginx
location = /xmlrpc.php { deny all; access_log off; log_not_found off; }

Reload NGINX only after validating the configuration:

bash
nginx -t && systemctl reload nginx

For Apache, a virtual host rule is preferable to relying on a plugin:

apache
Require all denied

On Apache 2.2-era configurations, the equivalent syntax differs, but those environments should be upgraded rather than preserved for convenience. Test the exact virtual host serving the site, not just a copied `.htaccess` snippet. Managed hosts may ignore or restrict `.htaccess` directives when the site runs behind NGINX.

A web application firewall or CDN rule can also block `POST` requests to `/xmlrpc.php`. That is useful when you do not control NGINX or Apache, but verify the request is stopped at the edge. A firewall rule that still sends traffic to PHP is less valuable during a flood.

If a service needs XML-RPC, allow only that service

Broadly enabling XML-RPC because one integration needs it is the common mistake. If the client uses fixed IP addresses, allow only those addresses and deny everyone else.

For example, an NGINX rule can permit an office network or known provider:

nginx
location = /xmlrpc.php { allow 198.51.100.24; allow 203.0.113.0/24; deny all;

include fastcgi_params; fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }

The PHP-FPM socket, include path, and FastCGI parameters vary by stack. Do not paste this block into production without matching it to the existing PHP location on that server. A bad override can create 502 errors, expose an incorrect document root, or bypass stack-specific security settings.

IP allowlisting does not fit every case. Mobile users have changing carrier addresses, and SaaS providers may publish large or changing address ranges. When IP restrictions are impractical, use layered controls: strong unique passwords, two-factor authentication for all administrator accounts, a web application firewall, method-level restrictions if supported, and aggressive rate limiting.

Avoid the weak fixes

A plugin that disables XML-RPC through a WordPress filter can be useful on shared hosting, but it is not the first choice. WordPress must load enough code to apply that filter, so the request can still consume PHP capacity. During brute-force traffic, that is exactly the resource you want to protect.

Likewise, blocking only `system.multicall` reduces one abuse path but leaves pingbacks and other methods exposed. It can be an acceptable compatibility compromise, not a complete hardening strategy.

Do not confuse XML-RPC controls with general account security. If an administrator password is reused, weak, or already exposed elsewhere, blocking XML-RPC does not fix the underlying risk. Enforce strong credentials, remove unused administrator accounts, review users after contractor access ends, and keep WordPress core, plugins, and themes patched.

Rate-limit what cannot be blocked

When a required client cannot use a stable IP range, rate limiting becomes the safety valve. Apply limits specifically to `xmlrpc.php`, not to the entire site. A global limit can accidentally throttle checkout callbacks, payment provider webhooks, inventory syncs, or legitimate API traffic.

An NGINX approach might define a request zone and apply it only to XML-RPC:

nginx
limit_req_zone $binary_remote_addr zone=xmlrpc_limit:10m rate=5r/m;

location = /xmlrpc.php { limit_req zone=xmlrpc_limit burst=5 nodelay; include fastcgi_params; fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }

Five requests per minute is only an example. A mobile publishing client may need more during an upload or sync. Start with observed normal traffic, set a conservative ceiling above it, and watch logs for rejected legitimate requests. If a client sends all traffic from a shared cloud IP, per-IP limiting may also affect unrelated users of that provider.

At the infrastructure layer, pair rate limiting with a WAF rule that blocks malformed XML, known malicious patterns, and obvious request floods. Keep logs long enough to investigate patterns. Security controls that cannot be audited are difficult to tune and easy to forget.

Verify the change without breaking operations

After deploying a rule, test from both an authorized and unauthorized network. Confirm that the endpoint returns the expected block response externally and that the required integration can still perform its actual job, not merely connect.

Then monitor three things for several days: web server status codes for `/xmlrpc.php`, PHP-FPM worker saturation, and application errors from the dependent service. On a WooCommerce site, also watch checkout and payment webhook behavior, even though they should not normally rely on XML-RPC. Production changes have a habit of revealing undocumented integrations.

Keep a rollback path. Make the change in staging where possible, record the prior server block, and take a tested backup before editing configuration. Automated hourly backups and isolated staging environments, such as the operational safeguards WP Tango prioritizes, turn a small access-control change into a reversible one rather than a late-night incident.

XML-RPC should be treated like any other exposed service: leave it available only when it earns its place, constrain it to the smallest practical audience, and verify that the control works under real traffic.

Keep reading