How to disable XML-RPC in WordPress, and when to leave it on
xmlrpc.php lets outside programs reach WordPress, and Jetpack and the mobile apps still use it. If nothing on your site does, switch off its login methods with a filter, remove its pingback methods, or refuse the file at the web server. Check the access log first.
- By
- WP Ministry
- Published
In short
- Jetpack and the WordPress mobile apps call xmlrpc.php. Check the access log for real use before you close it.
- The xmlrpc_
enabled filter switches off only the methods that need a login. Pingbacks stay on. - Removing pingback.ping with the xmlrpc_
methods filter works. Removing system.multicall the same way does nothing. - A rule at the web server refuses the file before WordPress starts, which is what saves the server work.
- A long password used nowhere else already makes guessing fail. Closing the file mainly removes load and noise.
xmlrpc.php is the file outside programs use to reach WordPress in an older format called XML-RPC. Jetpack and the WordPress mobile apps still call it. If nothing on your site does, you can close it in one of three ways: a filter that switches off the methods that need a login, a filter that removes the pingback methods, or a rule that makes the web server refuse the file.
Be clear about what you gain. A long password used nowhere else already makes guessing through this file fail. Closing it mainly takes away requests your server would otherwise answer, and the lines they leave in your logs.
What xmlrpc.php is and why it exists
XML-RPC lets one program run a named method on another over the web. The caller sends a POST request holding a small XML document: the method's name and its arguments. WordPress's XML-RPC server understands the old Blogger, MetaWeblog and Movable Type publishing formats, pingbacks, and WordPress's own methods for posts, pages, media, comments, users and options.
It was made for working on a site from somewhere other than the dashboard. Since WordPress 3.5 it has been on by default.
Newer tools use the REST API instead, which exchanges JSON and is what the block editor is built on. WordPress's core developers now call XML-RPC the legacy API. The file stays because some things still call it.
Two kinds of method matter for this decision.
- Methods that need a login. Publishing, editing, reading users and settings. Every call carries a username and a password, so every call is also a way to try a password.
- Methods that need none. The main one is
pingback.ping, which another site calls to say it has linked to one of your posts.
Find out whether anything uses it
If you close the file while something depends on it, that thing stops working. Check these first.
- Jetpack. Its documentation says Jetpack relies on the file to communicate with WordPress.com, and that the connection stops working properly if the file is blocked. Jetpack does not send a username and password through it. It signs each request with a secret token.
- The mobile apps. The apps' support pages list a publicly accessible XML-RPC file among the requirements for a site to work in the Jetpack app.
- Tools that publish from outside. A desktop editor, an automation service or a script that posts to the site may use the older publishing formats. Ask whoever set it up.
- Pingbacks. If you want other sites' link notifications to show among your comments, this is where they arrive.
Check the access log for real use
The access log shows who calls the file. Your host's control panel usually offers it as a download. Search it for the file's name:
grep "xmlrpc.php" access.log | tail -n 20In the standard log format, each line starts with the caller's address, shows the request in quotes followed by the status code, and ends with the name the caller gave itself. The log does not record which method was called, so judge by the pattern.
- Real use is POST requests from callers you can account for: your own address at the times you used the app, or addresses inside the ranges Jetpack publishes.
- Noise is POST requests from many addresses you do not know, arriving in bursts.
Look at a few weeks of the log. A tool that posts once a month will not show in one day's lines. If there are no POST requests you can account for, nothing you own is using the file.
The choices, side by side
| Choice | Password guessing through the file | Pingbacks | What the server still does |
|---|---|---|---|
| Leave it open and limit requests | Slowed | Accepted | Answers what the limit lets through |
| Switch off the methods that need a login | Stopped. No password is checked. | Accepted | Starts WordPress for every request |
| Remove the pingback methods | Unchanged | Refused | Starts WordPress for every request |
| Refuse the file at the server | Stopped | Stopped | Sends a short refusal. WordPress never starts. |
| A security plugin or a firewall | Depends on which of these it does | Depends | A firewall in front turns requests away before they reach the server |
The two filters can be used together. The server rule makes both unnecessary.
Leave it open and limit requests
If Jetpack or the app needs the file, this is your choice. WordPress's guidance for a site that uses XML-RPC is to restrict the file with firewall rules and to limit how often it can be called. Ask your host whether they limit requests to /. If they do not, WordPress firewalls compared covers the services that can.
Jetpack's documentation says you should be able to protect the file without allowing specific addresses, and names tools a host runs for this, such as fail2ban and ModSecurity. If you would rather let in only known callers, the rule is under "Allow only known addresses" below.
Switch off the methods that need a login
WordPress has a filter named xmlrpc_. Return false from it and every method that needs a login is switched off. WordPress answers such a call with "XML-RPC services are disabled on this site." and does not check the password it was sent.
The name promises more than the filter does, and WordPress's reference says so. It does not switch off pingbacks or any other method that needs no login. The file still answers, and each request still starts WordPress.
Anything that logs in through the file stops working once the filter is on. If you use Jetpack, check its connection afterwards.
Put the code in a small plugin of your own, so that it survives a change of theme.
Step 1: Create the plugin's file
In
wp-content/, create a folder namedplugins/ site-xmlrpc. Inside it, create a file namedsite-xmlrpc.phpwith this content.wp-content/plugins/ site-xmlrpc/ site-xmlrpc.php <?php /* * Plugin Name: Site XML-RPC settings */ add_filter( 'xmlrpc_enabled', '__return_false' );Step 2: Activate it
On the Plugins screen, find Site XML-RPC settings in the list and activate it.
Step 3: Check the answer
Send a login call with a made-up username and password. Replace
example.comwith your domain.Before the filter, the answer contains "Incorrect username or password." After it, the answer contains "XML-RPC services are disabled on this site."
bashcurl -s -d '<?xml version="1.0"?><methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value><string>nobody</string></value></param><param><value><string>not-a-password</string></value></param></params></methodCall>' https://example.com/xmlrpc.php
The same add_ line also works in a child theme's functions.php. How to create a WordPress child theme shows where that file goes. It stops applying when you switch themes.
To undo it, deactivate the plugin.
Remove the pingback methods
pingback.ping takes two addresses: a page that claims to link to you, and the post of yours it links to. To confirm the link, WordPress fetches the first address. That is the weakness. Anyone can ask your site to request a page on someone else's.
WordPress 3.5.1, in January 2013, fixed a way to use pingbacks to scan ports and make requests from the server. In March 2014 the security company Sucuri reported a flood in which more than 162,000 WordPress sites had been made to send requests to one site through pingback.ping. A site used this way has not been broken into. It has been borrowed.
There are two ways to stop accepting pingbacks.
- The setting. Under Settings, then Discussion, in "Default post settings", clear "Allow link notifications from other blogs (pingbacks and trackbacks) on new posts". WordPress fetches the other page only when the post accepts pings. The setting applies to new posts only, so posts you have already published keep what they had.
- The filter.
xmlrpc_removes the methods for every post at once. Add these lines to the plugin file from the section above, below what is there.methods
add_filter( 'xmlrpc_methods', 'site_remove_pingback_methods' );
function site_remove_pingback_methods( $methods ) {
unset( $methods['pingback.ping'] );
unset( $methods['pingback.extensions.getPingbacks'] );
return $methods;
}To check, ask the file for its list of methods and count the lines that mention pingbacks.
curl -s -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName><params></params></methodCall>' https://example.com/xmlrpc.php | grep -c "pingback"It prints 2 before the filter and 0 after. To undo it, remove the lines.
Why system.multicall cannot be removed this way
system.multicall runs several methods in one request. In October 2015 Sucuri described attackers using it to try hundreds of passwords in a single request, and WordPress's own guidance still names the method.
You may see advice to add unset( $methods['system.multicall'] ); to the function above. It has no effect. The method is not in the list the filter receives. The server underneath adds it, with two other system methods, after the filter has run.
It matters less than it did. WordPress was changed in the same month: once one login fails, every later login in the same request fails without being checked. One request no longer tries many passwords. With xmlrpc_ returning false, no login is checked at all.
Refuse the file at the server
If nothing uses XML-RPC, have the web server refuse the file. The request is turned away before PHP or WordPress starts. Of the changes you can make on the site itself, this is the only one that spares the server the work. These are the same rules as in how to protect WordPress from brute force attacks.
Keep a copy of the file before you change it, and try the rule on a staging site first if you have one.
.htaccess
<Files "xmlrpc.php">
Require all denied
</Files>On Apache, put the lines outside the block between # BEGIN WordPress and # END WordPress, because WordPress overwrites what is between those two lines. On nginx, the change applies once the configuration is reloaded. If WordPress is installed in a subfolder, the nginx path includes it, as in /.
To undo it, remove the lines. If every page shows an error after you saved .htaccess, the server could not read a line in it: see how to fix the 500 internal server error.
Allow only known addresses
This suits a site whose only caller has addresses that are published, such as Jetpack. It does not suit the mobile app, because a phone's address changes.
Replace 203.0.113.0/ with the ranges you want to let in. Jetpack lists its ranges on its allowlist page, and says they are subject to change, so a rule built on them has to be kept up to date.
.htaccess
<Files "xmlrpc.php">
Require ip 203.0.113.0/24
</Files>For more than one range, list them on the same line on Apache, separated by spaces. On nginx, add one allow line for each. On nginx the block needs the PHP lines, or the file will not run for the callers you let in. If a firewall service or CDN sits in front of the site, the server sees that service's address and not the caller's, so set the restriction at the service.
Let a security plugin or a firewall do it
Many security plugins have a setting for XML-RPC, and a firewall can refuse or limit requests to the file. WordPress security plugins compared and WordPress firewalls compared cover them.
A setting labeled as disabling XML-RPC may do any of the three things above. Read the plugin's documentation to see which, then check what the file answers.
Check what the file answers
Open https:// in a browser, with your own domain.
- Nothing changed yet. WordPress answers "XML-RPC server accepts POST requests only."
- After either filter. The same message. The filters change what the methods do, not whether the file answers, so use the two commands above.
- After the server rule. The server refuses the request with an error page of its own, normally 403 Forbidden.
If you see a refusal or "Not Found" before you have changed anything, your host has already closed the file. Jetpack's documentation notes that some hosts block it by default.
If you use Jetpack, look at it after any change. When requests from WordPress.com are being blocked, Jetpack shows a notice in the dashboard that points to Tools, then Site Health.
What closing it does not do
- It does not protect the login page.
wp-login.phptakes passwords too. The brute force guide linked above covers both. - It does not touch the REST API. That is a separate interface, and the block editor depends on it. Do not block it along with this file.
- It does not replace a strong password. XML-RPC has no step where a second factor could be asked for, so whether two-factor login covers this file depends on the plugin that adds it.
- It does not clean a site that is already infected. If you see an administrator you did not create, go to how to remove malware from a hacked WordPress site. Our WordPress security service starts with a one-time malware removal when a site is already hacked, and a care plan then keeps the site updated, scanned and backed up offsite.
Common questions
Will disabling XML-RPC break Jetpack or the mobile app?
Refusing the file at the server will. Jetpack's documentation says the connection stops working properly when the file is blocked, and the apps' support pages list a publicly accessible XML-RPC file as a requirement. Removing only the pingback methods leaves the login methods as they were. If you depend on either, leave the file open and have requests to it limited.
Does two-factor login protect xmlrpc.php?
Not by itself. A call to this file is not a login form, and there is no step where a code could be asked for. The plugin has to deal with it. The Two Factor plugin's listing says a regular password cannot be used to get around the two-factor requirement through XML-RPC or the REST API, and that those accept an application password instead. For any other plugin, read its listing. How to set up two-factor authentication in WordPress has the setup.
Can I just delete xmlrpc.php?
It will not last. The file is part of WordPress, and an update puts it back. A server rule or a filter stays in place through updates.
What is an application password, and does it change anything here?
It is a separate password WordPress makes for one app or script, which you can revoke without changing your own. It works with XML-RPC and with the REST API, and cannot be used on the login page. The apps' support pages say the Jetpack app creates one when you add another self-hosted site. It still travels through xmlrpc.php, so a closed file refuses it too.

