The User Control plugin gives administrators the possibility to disable user accounts in WordPress. Users whose accounts have been disabled cannot sign in to WordPress anymore. Unfortunately, the plugin has some serious vulnerabilites which anyone can use to perform SQL queries on the WordPress SQL database.
The plugin has been removed from the official WordPress plugin repository. If this plugin is installed on your WordPress installation, you should remove it ASAP.
The plugin contains the following code which is executed on every pageload:
if(isset($_POST['disable']))
{
foreach ( $_POST['users'] as $userid ) {
$wpdb->query("UPDATE ".$wpdb->prefix."usercontrol SET disable_status = 'disabled' WHERE ID = ".$wpdb->escape($userid));
}
}
if(isset($_POST['enable']))
{
foreach ( $_POST['users'] as $userid ) {
$wpdb->query("UPDATE ".$wpdb->prefix."usercontrol SET disable_status = 'enabled' WHERE ID = ".$wpdb->escape($userid));
}
}
This code is executed for logged-in users as well as anonymous users. There is no authentication necessary before that code is run.
Any website visitor can abuse this by sending an HTTP POST request with the variable disable=1
and users=1; /* some malicious SQL query statement here */
. The malicious SQL query will then be executed.
curl -X POST -d "disable=1&users=1%3B%20SELECT%20%2A%20FROM%20%60wp_options%60" http://localhost/
Well yes but no, if we focus mainly on the SQL injection part that's not how it should be solved. Because the problem is another. You see that
$wpdb->escape()
? well that is calling an old and deprecated function of wordpress that does not correctly escape the quotes. And that should already give you an idea of why there's an SQL injection vulnerability in there. How you would solve that is by changing$wpdb->escape
to$wpdb->prepare
or$wpdb-esc_sql
.