Advisory:

Several SQL injections in BuddyPress 1.7.1

Vulnerability

Last revised: July 1, 2013

BuddyPress 1.7.1 contains several SQL injections that allow arbitrary data to be retrieved.

SQL injection in groups filter

This is an example of an SQL injection via an HTTP request to BuddyPress. It modifies a request designed to return a list of groups so that, instead, it returns the entire contents of the wp_users table:

In both of the above examples, the request eventually results in a call to the get function in the BP_Groups_Group class. The get function builds an SQL query by appending strings together. If an attacker can control of the value of $include or $exclude they can modify the query by including the ) character (which is not escaped by the escape function) and then insert their own SQL. For example, if the value of $include is:

As already mentioned, to exploit the specific vulnerability in get, outlined above, the attacker needs to find a way to control the value of $include or $exclude. In the example HTTP requests also provided above, the attacker has chosen to focus on $include, attempting to smuggle it through as an extra parameter by URL encoding an ampersand (%26):

page=1%26include=0) union select * FROM wp_users --+

This means that when the URL is decoded, the value of page will actually be:

1&include=0) union select * FROM wp_users --+.

In this case, the page parameter is added the $qs array as:

page=1&include=0) union select * FROM wp_users --

A few lines later, the items in the $qs array are joined together in a new string, each separated by an ampersand, and assigned to a the $query_string variable. At this point, the ampersand that was contained in the value of the page parameter is indistinguishable from the ampersands separating the genuine parameter key-value pairs and our attacker has succeeded in smuggling the include parameter and its dangerous value (a SQL query fragment) through. The value of $query_string is returned by bp_dtheme_ajax_querystring and assigned to $args, where wp_parse_args takes the value of $args and breaks it into chunks, using the ampersand character as a delimiter, and returns an array ($r) containing each chunk as an item: The array is then passed to the extract function which assigns the values to local variables. The local variables (including $include) are then used during the construction of an instance of the BP_Groups_Template class which calls the BP_Groups_Template class which calls the aforementioned get function in BP_Groups_Group (p.2).

The method bp_has_members function is defined in buddypress/bp-members/bp-members-template.php, where bp_has_members calls the extract method, allowing the attacker to overwrite any local variable. This lets the attacker call new BP_Core_Members_Template (with any variables of our choosing. This in turn calls (amongst other functions ) get_users_by_letter which appends the $excludevariable straight into the SQL query.