23 Sep 2021

Vulnerability Details: Authenticated SQL Injection in MailPoet 2

The changelog for the latest version of the WordPress plugin MailPoet 2 is:

Fixed security issues, thank you to Mike for reporting these issues.

Some of the changes made in that version look to involve SQL statements and we confirmed that there was at least an authenticated SQL injection vulnerability fixed.

In the beginning of the function countSubscribers in the file /models/user.php this line was added to restrict the values contained in the array variable $list_ids to integers:

80
$list_ids = array_map('intval', $list_ids);

That variable is included in an SQL statement:

90
$where[] = 'C.list_id IN ('.implode(',',$list_ids).')';

The value of that variable is passed in to the function:

78
function countSubscribers(Array $list_ids = array(), $confirmed_subscribers = true)

That function is in called by the function can_subscribers_count_shortcode, where the value of the variable comes from user input, in the form of a shortcode attribute:

268
269
270
271
272
273
274
275
276
277
278
279
function scan_subscribers_count_shortcode($attributes) {
	$user = WYSIJA::get('user','model');
	$list_ids = !empty($attributes['list_id']) ? explode(',', $attributes['list_id']) : array();
 
	// if double optin is on we count only the confirmed subscribers, otherwise we count both confirmed and unconfirmed
	$confirmed_subscribers = false;
	$model_config = WYSIJA::get('config', 'model');
	if ($model_config->getValue('confirm_dbleoptin')){
		$confirmed_subscribers = true;
	}
 
	return $user->countSubscribers($list_ids, $confirmed_subscribers);

That function is in turn accessed through the shortcode “wysija_subscribers_count”:

14
add_shortcode('wysija_subscribers_count', array($this,'scan_subscribers_count_shortcode'));

As the proof of concept below, before that change, SQL injection was possible to anyone able to add a shortcode to a post or page.

Proof of Concept

Adding the following proof of concept to a post or page will cause varying amounts of time for tit  to fully load depending on how long you specify MySQL sleep function to run.

Replace “[sleep time]” with how many seconds you want sleep to occur for.

[wysija_subscribers_count list_id="1 )AND SLEEP([sleep time]"]

Leave a Reply

Your email address will not be published.