Posts Tagged ‘xmlrpc’

SQL Injection in WordPress.com Stats plugin

Overview

WordPress.com Stats is a plugin developed by Automattic, it lets self-hosted WordPress bloggers use the same traffic metrics system they provide to WordPress.com users. It tracks post and page views, referrers, search terms, and clicks on external links.

While testing this plugin I found a critical SQL Injection vulnerability that may allow an attacker to retrieve credentials from any user of a WordPress blog — the attacker only needs to know a valid user ID.

WordPress.com Stats 1.1 and previous versions are affected.

Technical Details

WordPress.com Stats plugin registers two new methods (wpStats.get_posts and wpStats.get_blog) on the WordPress XMLRPC server. The vulnerable method is wpStats.get_posts that interally maps to stats_get_posts.

php:
function stats_get_posts( $args ) {
list( $post_ids ) = $args;

$r = 'include=' . join(',', $post_ids);
$posts = get_posts( $r );
$_posts = array();

foreach ( $post_ids as $post_id )
$_posts[$post_id] = stats_get_post($post_id);

return $_posts;
}

Due to the lack of validation in stats_get_posts, an attacker can prepare a special XMLRPC request to pass arbitrary parameters and values to get_posts method — it’s posible because get_posts can receive a query string as a parameter.

get_posts accepts the following variables (defined in $defaults array).

php:
function get_posts($args) {
global $wpdb;

$defaults = array(
'numberposts' => 5, 'offset' => 0,
'category' => 0, 'orderby' => 'post_date',
'order' => 'DESC', 'include' => '',
'exclude' => '', 'meta_key' => '',
'meta_value' =>'', 'post_type' => 'post',
'post_status' => 'publish', 'post_parent' => 0
);
$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );

...
}

An attacker can prepare a special XMLRPC call to exploit the vulnerability:

code:
&meta_key=%27) SQL INJECTION HERE/*&meta_value=1

Solution

Upgrade to the latest version or apply the following patch to avoid SQL Injection attacks on WordPress.com Stats plugin.

diff:
Index: stats.php
===================================================================
--- stats.php   (revision 15884)
+++ stats.php   (working copy)
@@ -233,6 +233,7 @@
function stats_get_posts( $args ) {
list( $post_ids ) = $args;

+       $post_ids = array_map( 'intval', (array) $post_ids );
$r = 'include=' . join(',', $post_ids);
$posts = get_posts( $r );
$_posts = array();
 

category

archives

links

others