Introduction
xmlrpc.php is a WordPress file that enables remote communication between WordPress and external applications or services. While it provides useful functionality, attackers can abuse the XML-RPC endpoint to perform brute-force login attempts, password-guessing attacks, and other automated requests.
A common indication of an XML-RPC attack is a large number of POST requests to /xmlrpc.php appearing in the Nginx access or error logs. In some cases, excessive requests can also consume PHP-FPM resources and affect website performance.
This document explains how to identify and prevent unwanted access to xmlrpc.php using an Nginx configuration rule.
Prerequisites
Before implementing the configuration, ensure the following requirements are met:
- Root or sudo access to the server.
- Nginx is installed and actively serving the WordPress website.
- The WordPress website is running behind Nginx.
- Access to the Nginx virtual host/server configuration.
- Basic knowledge of Linux commands.
- A backup of the existing Nginx configuration is recommended before making changes.
- Confirm whether the website or any required integration actually uses XML-RPC functionality.
Check Nginx status
$ systemctl status nginx
Check the Nginx version
$ nginx -v
Backup the configuration
cp /etc/nginx/sites-enabled/default /etc/nginx/sites-enabled/default.bak
Important: If your website uses a separate Nginx virtual-host configuration, modify that configuration instead of
/etc/nginx/sites-enabled/default.
Implementation
Step 1: Identify XML-RPC Requests
Before blocking xmlrpc.php, review the Nginx logs and check whether the server is receiving repeated requests.
For example:
$ grep "xmlrpc.php" /var/log/nginx/access.log
To specifically check POST requests:
$ grep 'POST /xmlrpc.php' /var/log/nginx/access.log
You may see requests similar to:
xx.xx.xx.xx – – [17/Jul/2017:06:25:46] “POST /xmlrpc.php HTTP/1.0” 200
Continuous requests from multiple IP addresses can indicate automated scanning or an XML-RPC abuse attempt.
Step 2: Locate the Nginx Configuration
The default Nginx configuration is commonly located at:
$ /etc/nginx/sites-enabled/default
Open the configuration:
$ vi /etc/nginx/sites-enabled/default
If your WordPress website has its own virtual-host configuration, identify it first:
$ nginx -T
Then modify the appropriate server {} block.
Step 3: Block xmlrpc.php
Add the following configuration inside the appropriate server {} block:
location = /xmlrpc.php {
deny all;
}
For example:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html;
location = /xmlrpc.php {
deny all;
}
# Other WordPress configuration...
}
This configuration tells Nginx to deny requests made directly to:
/xmlrpc.php
The exact-match location:
location = /xmlrpc.php
ensures that the rule specifically applies to the xmlrpc.php endpoint.
Step 4: Test the Nginx Configuration
Before restarting Nginx, always check the configuration syntax:
$ nginx -t
A successful result should look similar to:
syntax is ok
test is successful
If you receive an error, do not restart Nginx until the configuration issue has been corrected.
Step 5: Reload Nginx
If the configuration test is successful, reload Nginx:
$ systemctl reload nginx
Alternatively:
$ service nginx reload
A reload is generally preferred because it applies the configuration without unnecessarily terminating existing connections.
If required, you can restart Nginx:
$ systemctl restart nginx
Verification
1. Test xmlrpc.php
From the server or another system, run:
$ curl -I https://example.com/xmlrpc.php
The request should return:
HTTP/1.1 403 Forbidden
This confirms that Nginx is denying access to the endpoint.
2. Test with POST
You can also test a POST request:
$ curl -X POST https://example.com/xmlrpc.php
The expected result should indicate that access is forbidden.
3. Check Nginx Logs
Review the access log:
$ grep "xmlrpc.php" /var/log/nginx/access.log
You should see requests returning a 403 status.
For example:
xx.xx.xx.xx – – “POST /xmlrpc.php HTTP/1.0” 403
This confirms that the request reached Nginx but was blocked by the configured rule.
Important Considerations
Before completely disabling XML-RPC, verify whether the website depends on it.
Some WordPress functionality or third-party integrations may use XML-RPC, including:
- Remote WordPress applications
- Certain publishing tools
- Legacy integrations
- Some plugins and external services
If XML-RPC is required by the website, completely blocking it may break that functionality.
In such cases, consider alternatives such as:
- Restricting access by IP.
- Using application-level protection.
- Rate limiting XML-RPC requests.
- Disabling only specific XML-RPC methods.
- Using a Web Application Firewall (WAF).
Conclusion
The WordPress xmlrpc.php endpoint can be targeted by automated brute-force and abuse attempts. Continuous POST requests to this endpoint can generate unnecessary PHP-FPM and server load.
For websites that do not require XML-RPC, blocking the endpoint at the Nginx level is a simple and effective preventive measure:
location = /xmlrpc.php {
deny all;
}
After implementing the rule, always:
$ nginx -t
$ systemctl reload nginx
Then verify the response and logs to confirm that requests to xmlrpc.php are being denied with HTTP 403 Forbidden.
FAQs
1. What is xmlrpc.php in WordPress?
xmlrpc.php is a WordPress endpoint that allows remote applications and services to communicate with a WordPress installation.
2. Why do attackers target xmlrpc.php?
Attackers can abuse XML-RPC for automated login attempts, brute-force attacks, and other types of unwanted requests.
3. How can I identify an XML-RPC attack?
Check the Nginx access logs:
$ grep "xmlrpc.php" /var/log/nginx/access.log
A large number of repeated POST /xmlrpc.php requests can indicate abuse.
4. How do I block XML-RPC using Nginx?
Add the following inside the appropriate server {} block:
location = /xmlrpc.php {
deny all;
}
5. Where should I add the configuration?
Add it to the Nginx virtual-host configuration for the affected WordPress website.
For example:
$ /etc/nginx/sites-enabled/default
However, the actual location may differ depending on your server configuration.
6. How do I verify the Nginx configuration?
Run:
$ nginx -t
Do not reload/restart Nginx if the configuration test reports an error.
7. What HTTP status should I receive after blocking XML-RPC?
Normally:
HTTP 403 Forbidden
8. Does blocking XML-RPC affect the WordPress website?
The normal WordPress website generally continues to work, but any functionality that specifically depends on XML-RPC may stop working.
Therefore, check the application’s requirements before blocking it.
9. Can I block only POST requests instead of blocking the entire XML-RPC endpoint?
Yes. Nginx can be configured with more granular rules, but completely blocking the endpoint is simpler when XML-RPC is not required.
10. Can I use a WAF instead of blocking XML-RPC?
Yes. A WAF can provide more granular protection, including rate limiting and filtering malicious requests, while potentially allowing legitimate XML-RPC traffic.
Talk to our experts:
For assistance with DevOps, cloud infrastructure, or server-related requirements, please reach out to our team through the link below.