SQL Injection in Post Indexer allows super admins to read the contents of the database


Last revised:

Post Indexer does not use prepared queries in many cases and in some of its database calls it uses backticks (`). These are not automatically escaped by WordPress, thus leading to the possibility of SQL injection.

In other places in the code it simply takes user controlled values and adds them to SQL queries.

An example of this is remove_post_older_than:

// classes/class.model.php line 589
function remove_posts_older_than( $unit, $period ) {
    // ...
    $sql = $this->db->prepare( "SELECT BLOG_ID, ID FROM {$this->network_posts} WHERE DATE_ADD(post_date, INTERVAL %d " . $period . ") < CURRENT_DATE() LIMIT %d", $unit, PI_CRON_TIDY_DELETE_LIMIT );
    $posts = $this->db->get_results( $sql );
    // ...

The value of $period is user-controlled and could easily be replaced with SQL:

// classes/cron.postindexerrebuild.php line 310
function process_tidy_agedposts($DEBUG = false) {
    // ...
    // The default is to remove posts from the index when they are over a year old
    $agedposts = get_site_option( 'postindexer_agedposts', array( 'agedunit' => 1, 'agedperiod' => 'year' ) );
    // ...
    $this->model->remove_posts_older_than( $agedposts['agedunit'], $agedposts['agedperiod'] );
    // ...

To exploit this vulnerability you need to be a super admin.

Current state: Fixed

CVSS Summary

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

Proof of concept

Advisory timeline

  1. 2016-11-01: Discovered
  2. 2016-11-14: Reported to plugin author via
  3. 2016-11-14: Plugin author responded
  4. 2016-11-17: Confirmed that version fixes the issue
  5. 2016-11-17: Requested CVE
  6. 2016-11-17: Advisory published

Mitigation/further actions

Upgrade to version or later.