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();
David Kierznowski 10:43 am on September 25, 2007 Enlace permanente
Alex, why am I not surprised you have another vulnerability to share
Is the vul public?
alex 11:32 am on September 25, 2007 Enlace permanente
David, is not public yet, however I do not plan to write any advisory.
David Kierznowski 1:08 pm on September 25, 2007 Enlace permanente
I hope you keep us in the loop champ! I think BlogSec may even sponsor this plugin, it may have some bugs, buts its an absolutely awesome project!
Roland Rust 12:32 am on September 26, 2007 Enlace permanente
Alex, BackUpWordPress is a beta release, I haven’t had too much support from experienced WordPress users until now. Please tell me more about the vulnerabilities you find in the plugin. Thanks a lot in advace!
Roland Rust 2:48 am on September 26, 2007 Enlace permanente
Alex, a bug-fix release of BackUpWordPress was released this moment. The plugin’s backup repository is now secured by .htaccess. I also have added capabilities to the Plugin, to allow the blog admin to download backup archives.
Thans a lot for pointing out security issues in BackUpWordPress!
alex 10:30 am on September 26, 2007 Enlace permanente
Well done Roland!, I didn’t answer before because I was sleeping
Roland Rust 3:55 pm on September 26, 2007 Enlace permanente
Alex, I’m happy to see some WordPress core developers having a look at my plugins. I have set up a forum (http://wpforum.designpraxis.at/) for support, bug reports, troubleshooting etc., if you happen to run into more security issues with my stuff, please let me know!