WordPress 3.5 was recently released which now comes with the WordPress API “always enabled”. Personally I think this adds unnecessary risk by increasing the attack surface. How many WordPress user’s actually use the API? I would put my money on it being a very small fraction, either way I’m sure the WordPress Core Development team had good reason to enable the API by default. After spending 5 minutes looking for where to turn the API off in WordPress 3.5 I gave up. Huh, I’ll have another look sometime soon.
I’ve had a play with the API in the past, however, I’ve always found it hard to get going as the information on how to interact with the API is a bit sparse. Having played with it for an hour or so this evening I thought I’d share some of the information on how to get started (as well as a self reminder ;).
The latest API calls can be found on WordPress’s Codex here. It doesn’t list all available calls, to find these let’s extract them from the ‘wp-includes/class-wp-xmlrpc-server.php’ file.
wp.getUsersBlogs wp.newPost wp.editPost wp.deletePost wp.getPost wp.getPosts wp.newTerm wp.editTerm wp.deleteTerm wp.getTerm wp.getTerms wp.getTaxonomy wp.getTaxonomies wp.getUser wp.getUsers wp.getProfile wp.editProfile wp.getPage wp.getPages wp.newPage wp.deletePage wp.editPage wp.getPageList wp.getAuthors wp.getCategories wp.getTags wp.newCategory wp.deleteCategory wp.suggestCategories wp.uploadFile wp.getCommentCount wp.getPostStatusList wp.getPageStatusList wp.getPageTemplates wp.getOptions wp.setOptions wp.getComment wp.getComments wp.deleteComment wp.editComment wp.newComment wp.getCommentStatusList wp.getMediaItem wp.getMediaLibrary wp.getPostFormats wp.getPostType wp.getPostTypes wp.getRevisions wp.restoreRevision blogger.getUsersBlogs blogger.getUserInfo blogger.getPost blogger.getRecentPosts blogger.newPost blogger.editPost blogger.deletePost metaWeblog.newPost metaWeblog.editPost metaWeblog.getPost metaWeblog.getRecentPosts metaWeblog.getCategories metaWeblog.newMediaObject metaWeblog.deletePost metaWeblog.getUsersBlogs mt.getCategoryList mt.getRecentPostTitles mt.getPostCategories mt.setPostCategories mt.supportedMethods mt.supportedTextFilters mt.getTrackbackPings mt.publishPost pingback.ping pingback.extensions.getPingbacks demo.sayHello demo.addTwoNumbers
As you can see from the above list there are a whole host of different things you can do via the API. Creating blog posts, requesting information about the blog’s settings and even uploading media! Most of these require authentication and use the same authorisation mechanisms as the GUI. The three I found not to require authentication were pingback.ping, demo.sayHello and demo.addTwoNumbers (there are probably others).
A typical API request body looks like the following:
<?xml version="1.0" encoding="iso-8859-1"?> <methodCall> <methodName>demo.sayHello</methodName> <params> <param></param> </params> </methodCall>
The xmlrpc.php file needs the valid XML sent to it as a POST request. The easiest way to do this in Linux is to use cURL. The following command will send the XML contained within the ‘demo.sayHello.txt’ file as a POST request to the remote WordPress API:
curl --data @demo.sayHello.txt http://www.example.com/xmlrpc.php
Which should return a response that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<params>
<param>
<value>
<string>Hello!</string>
</value>
</param>
</params>
</methodResponse>
Simple, eh?
Here are a few other WordPress API calls:
demo.addTwoNumbers
<?xml version="1.0" encoding="iso-8859-1"?> <methodCall> <methodName>demo.addTwoNumbers</methodName> <params> <param><value>2.0E+72</value></param> <param><value>2.0E+72</value></param> </params> </methodCall>
pingback.ping
<?xml version="1.0" encoding="iso-8859-1"?> <methodCall> <methodName>pingback.ping</methodName> <params> <param><value><string>http://www.example.com/index.php?p=71</string></value></param> <param><value><string>http://www.example2.com/index.php?p=72</string></value></param> </params> </methodCall>
wp.getPost
<?xml version="1.0" encoding="iso-8859-1"?> <methodCall> <methodName>wp.getPost</methodName> <params> <param><value>1</value></param> <param><value>username</value></param> <param><value>password</value></param> <param><value>72</value></param> </params> </methodCall>
wp.getUsers
<?xml version="1.0" encoding="iso-8859-1"?> <methodCall> <methodName>wp.getUsers</methodName> <params> <param><value>1</value></param> <param><value>username</value></param> <param><value>password</value></param> </params> </methodCall>
There you are, something to get you started playing around with the WordPress API. If you find out how to turn the damn thing off let me know! :)
EDIT —
After reading this post long time WPScan contributor (@_FireFart_) wrote a port scanner using a remote WordPress API! – https://github.com/FireFart/WordpressPingbackPortScanner
EDIT: 06.01.2013 00:55
An even more serious issue has been identified with WordPress’s XMLRPC API. ONsec research lab have found that the pingback API is vulnerable to ‘SSRF’ (Server Side Request Forgery): http://lab.onsec.ru/2013/01/wordpress-xmlrpc-pingback-additional.html
6 Responses
You can disable it easily.
Just add this filter:
add_filter( ‘xmlrpc_enabled’, ‘__return_false’ );
https://twitter.com/wpsecurenet
Actually, the above code, in testing, does NOTHING for WordPress 3.5. It may have worked in previous versions of WordPress, but in testing on my own site, it does NOT filter out the requests because Automatic has changed the actual class that handles the requests. To disable abuse and responses to xmlrpc.php add the following code to either your themes functions.php file, or create a stand alone plugin(something I will probably be putting out) that disables this via the class itself:
add_filter( ‘wp_xmlrpc_server_class’, ‘__return_false’ );
add_filter(‘xmlrpc_enabled’, ‘__return_false’);
works fine with my WP 3.5. A “405:XML-RPC services are disabled on this site. ” response is returned
I am on the other side of that fence! I am trying to get it to work again.
I have been using several curation programs. For a few years that not longer work.
Ron
thank you, you blog help me run the WordPress XML-RPC API on RESTConsole.
vwvfifm gktesb logwaqncb wmgqhy xhbtduve naykpkl rmjgoxibpao