Disable XML-RPC if nothing on your site uses it, because it gives attackers a login door with no rate limiting and a way to try hundreds of passwords in one request. But a few tools still need it, so check first. On our test site, a single system.multicall request carried 100 password guesses, and the server answered all 100 in 87 milliseconds.
This guide shows what still depends on XML-RPC, how to tell whether yours is active, and four ways to turn it off, all run on a WordPress 7.1.3 lab. If you only want pingbacks gone and the rest left alone, that is covered too.
What is xmlrpc.php, and is it on by default?
xmlrpc.php is a file in your WordPress root that lets outside software post to and manage your site over XML. It is on by default and has been since WordPress 3.5. There is no setting in the admin to turn it off.
On our test install, the file answered a system.listMethods call with 80 available methods and was reachable without any login. WordPress also advertises it on every page: the response carried an X-Pingback header pointing at xmlrpc.php, and the page’s <head> held a <link rel="EditURI" ... xmlrpc.php?rsd"> tag. An attacker scanning for targets does not have to guess the file is there; the site announces it.
The reason it matters for security is the system.multicall method. It bundles many calls into one HTTP request. An attacker uses it to try a long list of passwords against one username while making only a single request, which slips past anything that counts requests. We sent one multicall carrying 100 wp.getUsersBlogs login attempts; the server checked all 100 and returned 100 “Incorrect username or password” faults in 87 milliseconds (test T3).
Does anything on my site still need XML-RPC?
Some tools still need XML-RPC, so check before you block it. The ones that still rely on it are Jetpack’s connection to WordPress.com, the older WordPress mobile apps, pingbacks and trackbacks, and a few remote-publishing or automation integrations.
- Jetpack. Jetpack’s own troubleshooting docs say “Jetpack needs this file to connect to your website,” and that a host or security rule blocking
xmlrpc.phpbreaks the connection, which reconnecting won’t fix (Jetpack support). If you run Jetpack, don’t block the file outright; restrict it to WordPress.com’s addresses instead, or use the method below that disables logins but keeps the endpoint. - The WordPress mobile apps. Older versions sign in over XML-RPC. Newer builds accept application passwords, but a core proposal to stop XML-RPC from accepting normal passwords notes the apps still don’t fully support that flow (Trac #62789).
- Pingbacks and trackbacks. These run through XML-RPC. Most sites switched them off years ago to cut comment spam.
- Remote publishing or automation from a desktop editor or a service that connects over XML-RPC rather than the REST API.
If you use none of these, you can disable XML-RPC completely. If you use Jetpack or the apps, keep the file reachable and lock it down instead of blocking it.
How to check whether XML-RPC is active
To check whether XML-RPC is active, send one POST request to the file and read the answer. A live endpoint returns an XML response; a blocked one returns a 403 or 404.
From a terminal:
curl -s -X POST -d '<?xml version="1.0"?><methodCall><methodName>demo.sayHello</methodName></methodCall>' \
https://yoursite.com/xmlrpc.php
An active endpoint answers with <string>Hello!</string>. If you prefer not to use the command line, open https://yoursite.com/xmlrpc.php in a browser: a live file shows the line “XML-RPC server accepts POST requests only.” A blocked one shows your host’s 403 or a 404.
You can also look at your pages’ source for rel="pingback" or an X-Pingback header; if either points at xmlrpc.php, the endpoint is being advertised.
Four ways to disable XML-RPC
There are four ways to disable XML-RPC, and the right one depends on how much you want gone and whether you have server access. Each one below was run on our WordPress 7.1.3 test site; the result of each is from that test.
Method 1: A code snippet that disables authenticated methods
Add this filter through a code-snippets plugin or a small must-use plugin:
add_filter( 'xmlrpc_enabled', '__return_false' );
What it does, and what it does not do, surprised us until we read the core source. The filter is named xmlrpc_enabled, but WordPress core says it “only controls whether XML-RPC methods requiring authentication … are enabled” and that it “does not control whether pingbacks or other custom endpoints that don’t require authentication are enabled” (wp-includes/class-wp-xmlrpc-server.php).
Our test matched that exactly (test T4b). With the filter on:
wp.getUsersBlogswith the correct password returned “XML-RPC services are disabled on this site.” Good: login methods are off.system.multicallreturned the same. Good.demo.sayHellostill answered “Hello!”, andsystem.listMethodsstill listed 80 methods. The endpoint is still there.pingback.pingstill ran, because it needs no login.
So this snippet closes the brute-force door but leaves pingbacks open. For most sites that is half the job.
Method 2: A snippet that disables logins and pingbacks and stops advertising the file
To also remove pingbacks and the headers that announce the endpoint, use this instead. We wrote it for the test and saved it as a must-use plugin:
<?php
/**
* Plugin Name: Disable XML-RPC
* Description: Turns off XML-RPC logins and pingbacks and stops advertising xmlrpc.php.
*/
// Methods that need a username and password (wp.*, metaWeblog.*, system.multicall logins).
add_filter( 'xmlrpc_enabled', '__return_false' );
// Pingbacks don't need a login, so the filter above leaves them on. Remove them too.
add_filter( 'xmlrpc_methods', function ( $methods ) {
unset( $methods['pingback.ping'], $methods['pingback.extensions.getPingbacks'] );
return $methods;
} );
// Stop advertising the endpoint: the X-Pingback header and the RSD link in <head>.
add_filter( 'wp_headers', function ( $headers ) {
unset( $headers['X-Pingback'] );
return $headers;
} );
remove_action( 'wp_head', 'rsd_link' );
After activating it (test T8): pingback.ping returned “requested method pingback.ping does not exist,” the X-Pingback header was gone, and the RSD <link> tag was gone. system.listMethods dropped from 80 to 78. The file still exists, but it offers nothing an attacker can use and no longer announces itself.
This is the method we’d pick for a site that keeps Jetpack or the apps, because it leaves the endpoint reachable for application-password logins while removing the password-guessing and pingback paths.
Method 3: Block the file in nginx
If you have server access and nothing needs the file, refuse it before PHP runs. This is the lightest option, because the request never reaches WordPress.
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
On our test (T6), a POST to xmlrpc.php returned 403. One caveat: blocking the file this way does not remove the X-Pingback header, which WordPress still adds in PHP. The header points at a file that now 403s, which is harmless but untidy; add Method 2’s header removal if you want it gone.
Method 4: Block the file in Apache
For Apache, put this at the top of the .htaccess file in your site root, above the # BEGIN WordPress line:
<Files xmlrpc.php>
Require all denied
</Files>
On our test (T7), a POST to xmlrpc.php through Apache returned 403.
If you run Jetpack and must keep the file reachable, replace Require all denied with rules that allow only WordPress.com’s published IP ranges, as Jetpack’s docs describe, rather than blocking everyone.
Frequently Asked Questions
Will disabling XML-RPC break Jetpack or the WordPress app?
Blocking the file outright can. Jetpack connects to WordPress.com through xmlrpc.php, and the older mobile apps sign in over it, so denying the file breaks them. If you use either, don’t block it: use the code method that disables password logins while leaving the endpoint reachable, and sign in with application passwords, or restrict the file to WordPress.com’s IP ranges rather than denying everyone.
How do I check if XML-RPC is enabled on my WordPress site?
Send one POST request to /xmlrpc.php. A live endpoint answers with XML; on our test site a demo.sayHello call returned “Hello!”. If you’d rather not use the command line, open yoursite.com/xmlrpc.php in a browser: an active file shows “XML-RPC server accepts POST requests only”, while a blocked one returns a 403 or 404. You can also check pages for an X-Pingback header.
Does the xmlrpc_enabled filter fully disable XML-RPC?
No, and the name is misleading. WordPress core states the filter only controls methods that require authentication, so it stops password logins and system.multicall but leaves pingbacks, which need no login, still working. On our test site pingback.ping still ran with the filter on. To remove pingbacks too, also unset them with the xmlrpc_methods filter, as our plugin snippet does.
Is it safe to disable XML-RPC in WordPress?
For most sites, yes. If nothing you use depends on it, Jetpack, the mobile apps, pingbacks or a remote-publishing tool, disabling XML-RPC removes a login door that has no rate limiting, with no downside. Check first by listing what connects to your site. If something does need it, lock it down rather than blocking it, so you keep the feature without the brute-force exposure.
Which method should you use?
Which method you should use depends on what you run and what access you have.
- No Jetpack, no apps, and you have server access: block the file at the server (Method 3 or 4). It is the cheapest, since bad requests never touch PHP. Pair it with Method 2’s header removal for tidiness.
- No Jetpack, no apps, no server access: use Method 2 (the snippet). It removes logins and pingbacks and stops the file advertising itself, all from a plugin.
- You keep Jetpack or the mobile apps: don’t block the file. Use Method 1 or 2 to kill password logins and pingbacks while leaving the endpoint reachable, and sign in with application passwords instead. If you block at the server, restrict by IP rather than denying all.
- You only want pingback spam gone: the
xmlrpc_methodsfilter from Method 2 removes pingbacks on its own.
Whichever you choose, test it afterward with the curl command above and confirm the endpoint returns a 403 or “disabled” response. Disabling XML-RPC closes one brute-force path, but the normal login page is another; limiting login attempts there is covered in limiting login attempts. If you reached this page because of a wider hardening effort, the full checklist is the full WordPress security checklist.