xmlrpc.php is WordPress’s legacy remote-publishing API. Before the REST API existed, it let desktop editors, the WordPress mobile app and services like Jetpack talk to your site. Today it’s mostly a target: attackers use it for password brute-forcing and DDoS amplification.
Why it’s abused
system.multicalllets one HTTP request try hundreds of username/password combinations. Login rate limits onwp-login.phpdon’t see it.- Pingbacks can be abused to make your site send requests to a victim, joining a DDoS.
- Bot floods against
xmlrpc.phptie up PHP workers and can slow or crash a small server.
Check your access log to see how often it’s hit:
sudo grep -c "POST /xmlrpc.php" /var/log/nginx/access.log
Do you need it?
Probably not. You still need XML-RPC if you use:
- Jetpack (some features still use it),
- the WordPress mobile app with older configurations,
- old desktop blogging tools or integrations that only speak XML-RPC.
Everything modern — the block editor, the mobile app with application passwords, headless front ends — uses the REST API instead.
Option 1: block it in Nginx (best)
Blocking at the web server stops requests before they reach PHP, saving resources:
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
Or close the connection without any response:
location = /xmlrpc.php { return 444; }
Put it in the site’s server block, then:
sudo nginx -t && sudo systemctl reload nginx
Allow Jetpack only
If you use Jetpack, allow only Automattic’s IP ranges (check Jetpack’s documentation for the current list) and deny everyone else:
location = /xmlrpc.php {
allow 192.0.64.0/18; # example: verify against Jetpack's published ranges
deny all;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
Option 2: Apache / .htaccess
<Files xmlrpc.php>
Require all denied
</Files>
Add it to the virtual host (preferred) or the site’s .htaccess.
Option 3: a filter in WordPress
add_filter( 'xmlrpc_enabled', '__return_false' );
As a mu-plugin (wp-content/mu-plugins/disable-xmlrpc.php) it can’t be disabled by accident. Note: this filter disables authenticated XML-RPC methods, but requests still reach PHP (and some methods remain); blocking at the web server is more complete and cheaper. Plugins like “Disable XML-RPC” do the same thing.
Also remove the advertising header (optional)
WordPress announces the endpoint in an X-Pingback header and an RSD link. With XML-RPC blocked these are harmless, but you can remove them:
add_filter( 'wp_headers', function ( $headers ) {
unset( $headers['X-Pingback'] );
return $headers;
} );
remove_action( 'wp_head', 'rsd_link' );
Verify
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://example.com/xmlrpc.php
403 (deny) or no response (444) means it’s blocked. Before, WordPress answered 200 with “XML-RPC server accepts POST requests only.” on GET.
Fail2Ban as an extra layer
If you must keep XML-RPC open, ban IPs that hammer it. A jail matching POST /xmlrpc.php in the access log — see Fail2Ban for WordPress.
Related
On a WordPress VPS you can block abusive endpoints at the Nginx level, where it costs almost nothing.