Web Development

Reducing WordPress Load from XMLRPC


Every so often my website would get hit with high load but when I looked at the website analytics, I wouldn’t see any traffic that would explain it. It wasn’t until I was analyzing the nginx access logs through splunk that I realized what was causing it. Every couple days the xmlrpc.php file was getting hit hard by a bot.

What is XMLRPC?

This file is basically an old xml based remote procedure call (RPC) that allows 3rd party sites to query and interact with your wordpress via XML. You might get pingbacks from other sites or you might be using a plugin on your site that uses xmlrpc.

What Commands are Available:

blogger.deletePost
blogger.editPost
blogger.getPost
blogger.getRecentPosts
blogger.getUserInfo
blogger.getUsersBlogs
blogger.newPost
demo.addTwoNumbers
demo.sayHello
metaWeblog.deletePost
metaWeblog.editPost
metaWeblog.getCategories
metaWeblog.getPost
metaWeblog.getRecentPosts
metaWeblog.getUsersBlogs
metaWeblog.newMediaObject
metaWeblog.newPost
mt.getCategoryList
mt.getPostCategories
mt.getRecentPostTitles
mt.getTrackbackPings
mt.publishPost
mt.setPostCategories
mt.supportedMethods
mt.supportedTextFilters
pingback.extensions.getPingbacks
pingback.ping
system.getCapabilities
system.listMethods
system.multicall
wp.deleteCategory
wp.deleteComment
wp.deleteFile
wp.deletePage
wp.deletePost
wp.deleteTerm
wp.editComment
wp.editPage
wp.editPost
wp.editProfile
wp.editTerm
wp.getAuthors
wp.getCategories
wp.getComment
wp.getCommentCount
wp.getComments
wp.getCommentStatusList
wp.getMediaItem
wp.getMediaLibrary
wp.getOptions
wp.getPage
wp.getPageList
wp.getPages
wp.getPageStatusList
wp.getPageTemplates
wp.getPost
wp.getPostFormats
wp.getPosts
wp.getPostStatusList
wp.getPostType
wp.getPostTypes
wp.getProfile
wp.getRevisions
wp.getTags
wp.getTaxonomies
wp.getTaxonomy
wp.getTerm
wp.getTerms
wp.getUser
wp.getUsers
wp.getUsersBlogs
wp.newCategory
wp.newComment
wp.newPage
wp.newPost
wp.newTerm
wp.restoreRevision
wp.setOptions
wp.suggestCategories
wp.uploadFile           

Start with a Honeypot

In the world of security, a honeypot is a fake page that looks like the real thing. It is to lure in bad actors and then log what they do. So I moved my xmlrpc.php out of the way and wrote a honeypot that logs out everything that is trying to connect to xmlrpc. I left it for a few weeks.

If you are interested in running your own honeypot, replace your xmlrpc.php with:

<?php
$body = file_get_contents('php://input');
$trimedBody = preg_replace('/\s*/m', '',$body);

$logline  = date("Y/m/d.H:i:s")." IP:".$_SERVER['REMOTE_ADDR']. ' BODY:'.$trimedBody.PHP_EOL;
file_put_contents('/var/www/xmlrpc.log', $logline, FILE_APPEND);

echo '<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
  <fault>
    <value>
      <struct>
        <member>
          <name>faultCode</name>
          <value><int>-32601</int></value>
        </member>
        <member>
          <name>faultString</name>
          <value><string>server error. requested method does not exist.</string></value>
        </member>
      </struct>
    </value>
  </fault>
</methodResponse>';

The xmlrpc has lots of slow, legitimate uses. Then, about once a week, a bot comes in that runs thousands of large queries.

Blocking XMLRPC

The simplest way to deal with this is to just rename or delete the xmlrpc.php file from the root of your wordpress install. The bulk hits from this file are probably automated bots searching for vulnerable wordpress installations.

Don’t want to actually delete it, you can also tell nginx config to deny traffic to it by adding this to the virtual host:

// server * {
location xmlrpc.php {
  deny all;
}
// }

Filtering XMLRPC

However, instead of restricting all visitors of xmlrpc.php, what if instead we made it filter out common attacks. Most of the attacks are against system.multicall and attacking the `admin` user.

<?php
$body = file_get_contents('php://input'); 
if(str_contains($body, "admin")){
   exit 1;
}
include("xmlrpc-original.php")

Throttling XMLRPC

But what if you have a plugin or real traffic that needs to use xmlrpc page? Throttling might be the best route.

This is still a work in progress post, throttling is difficult to keep track of state.

openanalytics 3179 views

I'm a 35 year old UIUC Computer Engineer building mobile apps, websites and hardware integrations with an interest in 3D printing, biotechnology and Arduinos.


View Comments
There are currently no comments.

This site uses Akismet to reduce spam. Learn how your comment data is processed.