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

Score Vector Complexity Authentication Confidentiality Integrity Availability
Network Low Single Partial None None

You can read more about CVSS base scores on Wikipedia or in the CVSS specification.


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.

Proof of concept

Mitigation/further actions

Upgrade to version or later.