Nginx: 502 Bad Gateway / xmlrpc.php. Is your site under attack?

Last updated on

I recently found my web server unresponsive with a “502 Bad Gateway”. The Ubuntu process viewer revealed the php-fpm service running at 100% CPU. On further investigation, the Nginx access log showed thousands of entries for xmlrpc.php from multiple IP addresses and spoofed user agents, one purporting to be Google Bot.

/var/log/nginx/access.log
151.115.xx.xx - - [29/May/2017:22:42:44 +0100] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
151.115.xx.xx - - [29/May/2017:22:42:44 +0100] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"
185.188.xx.xx - - [29/May/2017:22:42:44 +0100] "POST /xmlrpc.php HTTP/1.1" 499 0 "-" "Googlebot/2.1 (+http://www.google.com/bot.html)"
185.188.xx.xx - - [29/May/2017:22:42:44 +0100] "POST /xmlrpc.php HTTP/1.1" 499 0 "-" "Googlebot/2.1 (+http://www.google.com/bot.html)"
185.188.xx.xx - - [29/May/2017:22:42:44 +0100] "POST /xmlrpc.php HTTP/1.1" 499 0 "-" "Googlebot/2.1 (+http://www.google.com/bot.html)"

What is xmlrpc.php?

XML-RPC is the API or “application program interface“ for WordPress that allows remote updates to WordPress from other applications. For the most part, XML-RPC is only truly useful if you’re planning to use mobile apps or remote connections to publish content on your website. As mobile use has been such a prevalent way to access the Internet, many people will use remote apps to make developing their WordPress sites much easier.

Method 1: A Quick Fix

A quick, temporary fix is to go to the root directory of your WordPress installation and rename xmlrpc.php to xmlrpc.php.bak. This method will stop attackers from querying XML-RPC, but anything that utilizes XML-RPC like Jetpack or the WordPress mobile app will cease to work.

Note: This is only a temporary fix because if WordPress is ever updated, it may restore xmlrpc.php.

Method 2: Permanently block xmlrpc.php

You can add a deny all rule to your server block in your Nginx config file.

sudo nano /etc/nginx/nginx.conf

nginx.conf may also call some other config files, so your server block may be located in:

sudo nano /etc/nginx/sites-enabled/default

If you are hosting multiple domains on Nginx, your server block might be in somewhere like:

sudo nano /etc/nginx/sites-enabled/example.com

Once you’ve found it, add the lines below within your server block.

/etc/nginx/nginx.conf
server {
    …
    location = /xmlrpc.php {
        deny all;
    }
    …
}

Save file and exit. (Press CTRL + X, press Y and then press ENTER)

Check that the Nginx config file is valid.

sudo nginx -t

If valid, reload Nginx service.

sudo service nginx reload

Note: This method will also stop anything that utilizes XML-RPC from functioning, including Jetpack or the WordPress mobile app.

Method 3 – Install the JetPack plugin

The Jetpack plugin for WordPress can block the XML-RPC multicall method requests with its Protect function. You will still see XML-RPC entries in your web server logs with Jetpack enabled. However, Jetpack will reduce the load on the database from these malicious log in attempts by nearly 90%.

The Protect function is automatically enabled, even if you skip the Jump Start process. You can now see a Jetpack dashboard which also displays the Protect function as being Active.

Doesn’t Cloudflare protect from these attacks?

The free edition of Cloudflare doesn’t support WAF (Web Application Firewall) to guard against pingback attacks via xmlrpc.php for WordPress. Enabling Clouflare’s ‘under attack mode’ won’t have any effect in the free edition.

Let me know in the comments if this helped. Follow me @DevAnswers or read more.

1 Star2 Stars3 Stars4 Stars5 Stars 4.67 (3 votes)

Feedback

Your email address will not be published. Required fields are marked *

We use Markdown to style comments, like on Github and Reddit.
To do a line break, type two spaces after the sentence.
You can add inline code by wrapping it in backticks: `code here`

    To do an entire block of code  
    type four spaces before the line
    and it will appear in a block like this.
    <-- four empty spaces