WordPress post: xmlrpc.php attack Prevention

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:

  1. Root or sudo access to the server.
  2. Nginx is installed and actively serving the WordPress website.
  3. The WordPress website is running behind Nginx.
  4. Access to the Nginx virtual host/server configuration.
  5. Basic knowledge of Linux commands.
  6. A backup of the existing Nginx configuration is recommended before making changes.
  7. 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.

https://pheonixsolutions.com/contact

admin

Writes about Web & Architecture at Pheonix Solutions.

Leave a Reply

Scroll to Top