Diagnosing and Mitigating High CPU Usage from WordPress XML-RPC Brute Force Attacks

A deep dive into identifying, troubleshooting, and permanently stopping WordPress XML-RPC (xmlrpc.php) brute force and amplification attacks that cause severe high CPU usage and server instability.

Diagnosing and Mitigating High CPU Usage from WordPress XML-RPC Brute Force Attacks

One of the most persistent and resource-draining issues faced by Linux systems administrators managing large-scale WordPress hosting environments is the dreaded XML-RPC brute force attack. While standard HTTP flood attacks are common, XML-RPC attacks are particularly devastating due to their amplification capabilities. A single malicious HTTP request to xmlrpc.php can force the server to execute hundreds of login attempts or pingbacks, rapidly exhausting PHP-FPM workers, maxing out CPU utilization, and eventually causing a complete database or web server crash.

In this deep-dive diagnostic guide, we will explore how to properly identify an ongoing XML-RPC attack at the OS level, analyze the traffic, and implement robust mitigations across Apache, Nginx, and LiteSpeed.

The Symptoms: Why is the Server Crashing?

The initial symptoms usually present as general server unresponsiveness. Upon logging in via SSH, you might run top or htop and see a massive spike in system load:

top - 16:10:45 up 14 days, 3:22,  1 user,  load average: 45.22, 38.10, 22.05
Tasks: 350 total,   5 running, 345 sleeping,   0 stopped,   0 zombie
%Cpu(s): 85.5 us, 12.0 sy,  0.0 ni,  1.5 id,  0.0 wa,  0.0 hi,  1.0 si,  0.0 st
MiB Mem :  32045.2 total,   1024.1 free,  29000.5 used,   2020.6 buff/cache
MiB Swap:   4096.0 total,    512.0 free,   3584.0 used.   1200.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
12044 www-data  20   0  350020  45200  28100 R  98.0   0.1   0:05.12 php-fpm
12045 www-data  20   0  351040  46100  28100 R  97.5   0.1   0:04.98 php-fpm
12046 www-data  20   0  350020  45000  28000 R  95.0   0.1   0:04.55 php-fpm
...

If you check the web server access logs, you will notice an abnormally high rate of POST requests specifically targeting /xmlrpc.php.

tail -f /var/log/nginx/access.log | grep xmlrpc

Output:

192.168.1.100 - - [18/Sep/2026:16:11:02 +0000] "POST /xmlrpc.php HTTP/1.1" 200 452 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."
192.168.1.101 - - [18/Sep/2026:16:11:02 +0000] "POST /xmlrpc.php HTTP/1.1" 200 452 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."
192.168.1.102 - - [18/Sep/2026:16:11:03 +0000] "POST /xmlrpc.php HTTP/1.1" 200 452 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."

Because these requests return an HTTP 200 (Success) status, many standard rate-limiting setups that look for HTTP 401s (Unauthorized) or 403s (Forbidden) completely miss the ongoing attack.

The Core Mechanism: System Call Amplification

What makes XML-RPC unique? Attackers utilize the system.multicall method. Inside a single XML payload, an attacker can bundle thousands of wp.getUsersBlogs or wp.getComments requests.

When Nginx hands this off to PHP-FPM, WordPress bootstrap (wp-load.php) is loaded into memory, and it iterates through the XML payload, repeatedly querying the MySQL database for password hashes and executing heavy Bcrypt/MD5 hashing operations. This CPU exhaustion is what causes the high load.

Diagnosing the Scale of the Attack

To quantify the attack and identify the top offending IPs, use awk on your access logs:

awk '/xmlrpc.php/ {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10

If you manage a multi-tenant cPanel or DirectAdmin server, you might want to identify which specific virtual host is under attack:

grep -r "POST /xmlrpc.php" /var/log/apache2/domains/ | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 5

Step 1: Immediate Mitigation via Web Server Configuration

The fastest way to drop the load is to block access to xmlrpc.php at the edge (the web server level), preventing the request from ever reaching PHP-FPM.

For Nginx

Open your site’s virtual host configuration block (e.g., /etc/nginx/sites-available/wordpress) and add:

location = /xmlrpc.php {
    deny all;
    access_log off;
    log_not_found off;
    # Alternatively, drop the connection entirely without returning a 403:
    # return 444; 
}

Reload Nginx:

nginx -t && systemctl reload nginx

For Apache (.htaccess or VirtualHost)

If you are using Apache on a cPanel server, you can apply this globally via WHM’s Include Editor, or per-site in the .htaccess file:

<Files xmlrpc.php>
    Order Allow,Deny
    Deny from all
</Files>

For LiteSpeed / OpenLiteSpeed

LiteSpeed reads .htaccess natively, so the Apache rule above will work. However, for a more robust server-wide block, you can use a rewrite rule in the LiteSpeed WebAdmin Console:

RewriteRule ^/(.*)xmlrpc\.php$ - [F,L]

Step 2: Advanced Network-Level Mitigation (Fail2Ban & iptables)

While returning a 403 Forbidden reduces CPU load, your web server still has to process the TCP connection. In a massive volumetric botnet attack, even 403s can overwhelm socket buffers and cause nf_conntrack drops.

If you are dealing with a severe attack, you must drop the traffic at the firewall level. You can use Fail2Ban to parse the access logs and automatically ban IPs hitting xmlrpc.php.

Create a new Fail2Ban filter /etc/fail2ban/filter.d/wordpress-xmlrpc.conf:

[Definition]
failregex = ^<HOST> .*POST .*xmlrpc\.php.*
ignoreregex =

And configure the jail in /etc/fail2ban/jail.local:

[wordpress-xmlrpc]
enabled = true
port = http,https
filter = wordpress-xmlrpc
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 60
bantime = 3600

Restart Fail2Ban:

systemctl restart fail2ban

When Software Mitigation Isn’t Enough: Hardware and Infrastructure Scaling

If your environment is heavily targeted by distributed brute force or Layer 7 amplification attacks, relying on shared hosting CPU limits or small VPS instances can lead to recurring downtime. No matter how finely tuned your software stack is, network interface bottlenecks and CPU steal time on a noisy hypervisor will throttle your mitigation efforts.

To absorb massive XML-RPC brute force attacks, handle high concurrent connections, and utilize advanced hardware-level firewalling, migrating to unmetered, DDoS-protected bare-metal Dedicated Servers is often the definitive solution. Furthermore, for hosting providers or businesses aiming to target the South Asian demographic with minimal latency while retaining ironclad hardware defense, deploying your stack on Dedicated Servers in Pakistan ensures that the traffic is handled locally on enterprise-grade hardware without routing bottlenecks.

Conclusion

XML-RPC is largely considered a legacy feature in the WordPress ecosystem, heavily superseded by the modern WordPress REST API. Disabling it at the web server level not only immediately resolves CPU spikes caused by brute force attacks but also significantly hardens your server’s security posture. By combining Nginx/Apache blocks with network-level iptables rules via Fail2Ban, and backing it all with robust hardware, you can permanently eradicate XML-RPC induced server crashes.