How to Enable and Disable xmlrpc.php in WordPress (And Why It Matters)
The xmlrpc.php file is a core WordPress component that exposes an XML-RPC API endpoint, allowing remote applications to authenticate and execute server-side operations — publishing posts, managing comments, triggering pingbacks, and more. Because it accepts unauthenticated POST requests by default and processes them before most security layers activate, it is one of the most frequently abused attack surfaces in any WordPress installation.
If you do not use the WordPress mobile app, Jetpack, or any third-party service that explicitly requires XML-RPC, disabling xmlrpc.php is the correct default security posture. If you do rely on those integrations, you can harden the endpoint rather than remove it entirely.
What Is xmlrpc.php and How Does It Work
XML-RPC (Extensible Markup Language Remote Procedure Call) is a protocol that encodes function calls in XML and transmits them over HTTP. WordPress has shipped a full XML-RPC server since version 3.5, implemented in the xmlrpc.php file located in the WordPress root directory.
When a remote client — a mobile app, a desktop blogging client, or an automation script — sends a POST request to https://yourdomain.com/xmlrpc.php, WordPress parses the XML payload, authenticates the credentials embedded in the request body, and executes the requested method. The entire exchange happens in a single HTTP round-trip, which is both its strength and its fundamental weakness from a security standpoint.
Core XML-RPC Methods Exposed by WordPress
wp.newPost/wp.editPost— create and update posts remotelywp.getComments/wp.deleteComment— manage commentswp.uploadFile— upload media to the serverpingback.ping— notify a remote site that it has been linkedsystem.multicall— batch multiple method calls into a single HTTP request
The system.multicall method is particularly dangerous. A single HTTP request can bundle hundreds of wp.getUsersBlogs calls, each testing a different password. This allows an attacker to perform thousands of authentication attempts while generating only one server log entry, bypassing rate-limiting tools that count individual requests.
Security Risks of Leaving xmlrpc.php Enabled
Brute Force Amplification via system.multicall
Traditional brute force attacks send one credential pair per HTTP request. With XML-RPC, an attacker wraps 500 login attempts inside a single system.multicall payload. A standard fail2ban rule or login-attempt counter sees one request; the attacker gets 500 guesses. This is not a theoretical risk — it is the most common XML-RPC exploit observed in the wild.
Pingback-Amplified DDoS
WordPress automatically processes incoming pingback requests through xmlrpc.php. An attacker can send a crafted pingback.ping request to thousands of WordPress sites, instructing each one to send an HTTP request to a single victim URL. The victim receives a volumetric flood of requests originating from legitimate WordPress servers, making IP-based blocking ineffective. Your server simultaneously becomes a victim (resource exhaustion) and an unwilling attack amplifier.
SSRF via Pingback
The pingback mechanism can be abused for Server-Side Request Forgery (SSRF). An attacker sends a pingback.ping request where the source URL points to an internal network resource — http://192.168.1.1/admin, for example. The WordPress server fetches that URL from inside the network perimeter, potentially exposing internal services that are not publicly routable.
Credential Exposure in Transit
XML-RPC transmits credentials in the POST body as plain text within the XML envelope. If your site does not enforce HTTPS, credentials are exposed to any network observer. Even with TLS, the credentials are embedded in every single request — there is no session token or OAuth flow to limit the exposure window.
When You Should Keep xmlrpc.php Enabled
Disable it by default, but keep it enabled if your workflow genuinely depends on any of the following:
- WordPress mobile app (iOS/Android): The official app uses XML-RPC for all site management operations on self-hosted WordPress installations.
- Jetpack plugin: Several Jetpack modules — including publicize, mobile push notifications, and some stats features — communicate via XML-RPC to WordPress.com servers.
- Desktop blogging clients: MarsEdit, Windows Live Writer, and similar tools rely exclusively on the XML-RPC API.
- Automated publishing pipelines: IFTTT, Zapier, and custom scripts that push content to WordPress often use XML-RPC when the REST API is not configured.
- Pingbacks/trackbacks between WordPress sites: If cross-site pingback notifications are part of your editorial workflow, disabling
xmlrpc.phpsilences them.
If none of these apply, there is no operational reason to leave the endpoint open.
xmlrpc.php vs. the WordPress REST API
WordPress introduced the REST API in version 4.7 as a modern, token-based replacement for XML-RPC. Understanding the differences helps you decide whether disabling XML-RPC breaks anything critical.
| Feature | xmlrpc.php | WordPress REST API |
|---|
| — | — | — |
|---|
| Authentication | Username + password in every request | Application passwords, OAuth, JWT |
|---|
| Transport | HTTP POST only | HTTP GET, POST, PUT, PATCH, DELETE |
|---|
| Payload format | XML | JSON |
|---|
| Introduced | WordPress 1.5 (2005) | WordPress 4.7 (2016) |
|---|
| Brute force risk | High (system.multicall) | Lower (per-request, rate-limitable) |
|---|
| SSRF via pingback | Yes | No |
|---|
| Mobile app support | Yes (legacy) | Yes (current) |
|---|
| Jetpack dependency | Partial | Partial |
|---|
| Granular permission scopes | No | Yes (application passwords) |
|---|
| Recommended for new integrations | No | Yes |
|---|
If you are building a new integration or migrating an existing one, use the REST API. The authentication model is significantly more secure, and the endpoint is far easier to audit and rate-limit at the infrastructure level.
How to Disable xmlrpc.php in WordPress
Choose the method that matches your server access level and risk tolerance. Methods are ordered from lowest to highest server-level enforcement.
Method 1: Disable via Plugin (Quickest, No Server Access Required)
For shared hosting environments or sites where you prefer not to edit server configuration files, a plugin is the most accessible option.
Recommended plugins:
- Disable XML-RPC-API — single-purpose, minimal footprint, activates instantly
- All In One WP Security and Firewall — broader security suite with granular XML-RPC controls
Steps for Disable XML-RPC-API:
- Navigate to Plugins > Add New in your WordPress dashboard.
- Search for "Disable XML-RPC-API" and click Install Now, then Activate.
- No further configuration is required — the plugin hooks into
xmlrpc_enabledand returns false immediately on activation.
Steps for All In One WP Security and Firewall:
- After activating the plugin, go to WP Security > Firewall.
- Locate the XML-RPC section.
- Enable the option to completely block XML-RPC requests.
- Save settings.
Limitation: Plugin-based blocking fires inside the WordPress PHP execution context. The server still boots PHP, loads WordPress, and processes the request before rejecting it. Under a heavy attack, this consumes CPU and memory. For high-traffic sites under active attack, use the .htaccess or Nginx method instead.
Method 2: Disable via .htaccess (Apache — Server-Level Block)
Blocking at the .htaccess level prevents PHP from executing at all for requests targeting xmlrpc.php. This is significantly more efficient under load.
- Connect to your server via FTP, SFTP, or your hosting file manager and open the
.htaccessfile in your WordPress root (typicallypublic_html/.htaccess). - Add the following block. Place it before the standard WordPress rewrite rules:
# Block all access to xmlrpc.php
<Files "xmlrpc.php">
Order Deny,Allow
Deny from all
</Files>- Save the file.
To verify the block is active, run a test from your local machine:
curl -s -o /dev/null -w "%{http_code}" -X POST https://yourdomain.com/xmlrpc.phpYou should receive a 403 response. A 200 or 405 means the block is not yet in effect.
Edge case — if you still need pingbacks from specific trusted IPs, you can whitelist them:
<Files "xmlrpc.php">
Order Deny,Allow
Deny from all
Allow from 192.0.2.10
</Files>Method 3: Disable via Nginx Configuration
If your server runs Nginx (common on VPS Hosting environments), .htaccess files have no effect. Add the block directly to your site's server block configuration.
# Block xmlrpc.php at the Nginx level
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
return 444;
}The return 444 directive closes the TCP connection without sending an HTTP response, which is more efficient than a 403 because it prevents the attacker's client from receiving any feedback. After editing, reload Nginx:
sudo nginx -t && sudo systemctl reload nginxPlace this location block inside your server {} block, before any try_files or PHP processing directives.
Method 4: Disable via functions.php (WordPress Filter Hook)
This method uses a WordPress filter to disable XML-RPC at the application layer. It is less efficient than server-level blocking but useful when you lack direct server access and want a code-based solution without a plugin dependency.
- Go to Appearance > Theme Editor in your WordPress dashboard, or access the file directly via SFTP at
wp-content/themes/your-theme/functions.php. - Add the following to the end of the file:
// Disable XML-RPC completely
add_filter( 'xmlrpc_enabled', '__return_false' );- Save the file.
Important caveat: This filter disables authenticated XML-RPC methods, but it does not block the pingback.ping method or prevent the file from being accessed. The server still processes the request up to the point where WordPress evaluates the filter. For complete protection, combine this with the .htaccess or Nginx block.
If you are using a child theme, always add custom code to the child theme's functions.php, not the parent theme. Parent theme updates will overwrite your changes.
Method 5: Selective Disable — Block Pingbacks Only
If you need XML-RPC for Jetpack or mobile publishing but want to eliminate the DDoS amplification vector, you can disable only the pingback method while keeping the rest of the API functional.
// Disable only the pingback method, keep XML-RPC otherwise functional
add_filter( 'xmlrpc_methods', function( $methods ) {
unset( $methods['pingback.ping'] );
unset( $methods['pingback.extensions.getPingbacks'] );
return $methods;
} );Add this to your child theme's functions.php or a site-specific plugin. This is the recommended configuration for sites that run Jetpack but do not need to receive pingbacks.
How to Re-Enable xmlrpc.php
Reversing any of the above methods restores XML-RPC access:
- Plugin method: Deactivate or delete the blocking plugin from Plugins > Installed Plugins.
- .htaccess method: Remove the
<Files "xmlrpc.php">block from.htaccessand save. - Nginx method: Remove the
location = /xmlrpc.phpblock from your server configuration and reload Nginx withsudo systemctl reload nginx. - functions.php method: Remove the
add_filter( 'xmlrpc_enabled', '__return_false' )line and save.
After re-enabling, verify the endpoint responds correctly:
curl -s -X POST https://yourdomain.com/xmlrpc.php
-H "Content-Type: text/xml"
--data '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName><params></params></methodCall>'A valid XML response listing available methods confirms the endpoint is active.
Hardening xmlrpc.php Without Disabling It
If disabling is not an option, apply these mitigations to reduce the attack surface:
Enforce HTTPS: Ensure your site uses a valid TLS certificate. If you have not already, configure one through your hosting provider — SSL Certificates prevent credential interception in transit.
Rate-limit at the firewall or CDN level: Configure your WAF (Cloudflare, ModSecurity) to limit POST requests to xmlrpc.php to a maximum of 5–10 per minute per IP.
Block system.multicall specifically:
add_filter( 'xmlrpc_methods', function( $methods ) {
unset( $methods['system.multicall'] );
return $methods;
} );This eliminates the brute force amplification vector while preserving all other XML-RPC functionality.
Restrict by IP: If you only access XML-RPC from known IP addresses (your mobile app's carrier IP range, or a static office IP), whitelist those addresses in .htaccess or Nginx and deny all others.
Monitor access logs: Regularly audit your server logs for repeated POST requests to xmlrpc.php. A spike in 200-status POST requests to this file is a reliable indicator of an ongoing brute force campaign.
On a VPS with cPanel or other managed panel environment, you can configure ModSecurity rules directly from the control panel to enforce these restrictions without manual file editing.
Choosing the Right Method: Decision Matrix
| Your Situation | Recommended Method |
|---|
| — | — |
|---|
| Shared hosting, no server access | Plugin (Disable XML-RPC-API) |
|---|
| Apache server, full file access | .htaccess block |
|---|
| Nginx server (VPS/Dedicated) | Nginx location block |
|---|
| Need Jetpack but not pingbacks | Selective filter in functions.php |
|---|
| Need full XML-RPC (mobile app) | Harden with rate limiting + block system.multicall |
|---|
| Under active brute force attack | Nginx `return 444` + server firewall rule |
|---|
| Managed WordPress on cPanel VPS | ModSecurity rule via cPanel WAF |
|---|
For production sites hosted on Dedicated Servers, the Nginx or Apache server-level block is always preferable to a plugin-based solution because it prevents PHP execution entirely for malicious requests, eliminating the CPU overhead that plugin-based blocking incurs under sustained attack.
Practical Key-Takeaway Checklist
- Audit whether any active plugin or service in your stack actually requires XML-RPC before disabling it — check Jetpack, mobile apps, and any publishing automation tools.
- If no dependency exists, apply the server-level block (
.htaccessor Nginx) rather than a plugin — it is more efficient and survives plugin deactivation. - If you must keep XML-RPC active, unconditionally remove
system.multicallandpingback.pingvia thexmlrpc_methodsfilter — these two methods account for the vast majority of XML-RPC abuse. - Always enforce HTTPS on any WordPress site that accepts authenticated requests, including XML-RPC.
- After applying any block, verify with
curlthat the endpoint returns403or drops the connection — do not assume the configuration is correct without testing. - On Nginx-based VPS or dedicated server environments, use
return 444instead ofdeny allto avoid giving attackers any HTTP-level feedback. - Log and monitor POST requests to
xmlrpc.php— a sudden spike is an early warning of a credential-stuffing or DDoS amplification campaign. - If you manage multiple WordPress sites, consider centralizing this configuration at the server or CDN level rather than applying per-site plugin rules.
For sites that need robust remote management without the XML-RPC risk surface, migrating integrations to the WordPress REST API with application passwords is the correct long-term path. The REST API provides per-token revocation, scoped permissions, and standard HTTP semantics that are far easier to secure and audit.
If you are setting up a new WordPress environment and want a clean, secure baseline from the start, VPS Control Panels with ModSecurity pre-configured give you server-level WAF protection without requiring manual rule authoring.
—
Frequently Asked Questions
Does disabling xmlrpc.php break the WordPress REST API?
No. The REST API (/wp-json/) is a completely separate endpoint with its own authentication and routing. Blocking xmlrpc.php has zero effect on REST API functionality. The two systems are architecturally independent.
Will disabling xmlrpc.php break Jetpack?
It depends on which Jetpack modules you use. Jetpack has progressively migrated features to the REST API, but some older modules — including certain publicize and notification features — still communicate via XML-RPC. Check the Jetpack debug page at Jetpack > Dashboard > Debug to see if XML-RPC connectivity is listed as a requirement before disabling it.
Is the .htaccess method or the functions.php method more secure?
The .htaccess method is significantly more secure under attack conditions. It blocks the request at the web server layer before PHP loads, consuming minimal resources. The functions.php filter fires inside WordPress's PHP execution context, meaning the server still bootstraps WordPress for every blocked request — which is expensive under a high-volume attack.
Can an attacker still exploit xmlrpc.php if I only disable it via the WordPress filter?
Partially. The xmlrpc_enabled filter prevents authenticated method calls, but the file remains publicly accessible and the server still processes incoming requests. The pingback endpoint may remain partially functional depending on WordPress version. For complete protection, pair the filter with a server-level block.
How do I check if xmlrpc.php is currently accessible on my site?
Run the following command from your local terminal, replacing the domain with your own:
curl -s -o /dev/null -w "%{http_code}" -X POST https://yourdomain.com/xmlrpc.phpA 200 response means the endpoint is open. A 403 or a connection drop (000) confirms it is blocked. You can also use the online tool at xmlrpc.eritreo.it to test pingback vulnerability specifically.
