28 Mar

Privilege Escalation Vulnerability in Easy Updates Manager

Yesterday we noted how two of the most popular WordPress plugins were insecurely using the function extract(), as they were extracting the $_POST variable, which involves untrusted user input and the documentation for that function warns against:

Warning Do not use extract() on untrusted data, like user input (e.g. $_GET, $_FILES).

We found that usage through a website WPDirectory, which we ran across recently, that makes it easy to check the code of all the plugins in WordPress’ Plugin Directory at once. When we ran a check for plugins doing the exact same thing with the $_REQUEST variable, those plugins were again flagged as well as the plugin Easy Updates Manager:

The code in that plugin turns out to be insecure as well.

Seeing as most of the most popular plugins that are extracting user input like this have vulnerabilities caused by it, we have added a new check to our Plugin Security Checker that flags this, so you can now check plugins you use to see if they might have similar issues with that tool.

That plugin registers the function ajax_handler() to be accessible through WordPress’ AJAX functionality by anyone logged in to WordPress:

add_action('wp_ajax_eum_ajax', array($this, 'ajax_handler'));

The relevant code in that function is as follows:

public function ajax_handler() {
	if (empty($_REQUEST)) return;
	if (!wp_verify_nonce($nonce, $nonce_key) || empty($subaction)) die('Security check');
	$results = array();
	$data = isset($data) ? $data : array();
	if (!method_exists($this, $subaction)) {
		do_action('eum_premium_ajax_handler', $subaction, $data);
		error_log("EUM: ajax_handler: no such command (".$subaction.")");
		die('No such command');
	} else {
		$results = call_user_func(array($this, $subaction), $data);

That code does have some security in place, since it checks for a valid nonce to prevent cross-site request forgery (CSRF), but since user input specifies what nonce is check, access to a valid value for any nonce is good enough to get access to the functions code. Since CSRF involves causing someone else to take an action they didn’t intend, the code is working as intended, but since that is the only security in place the code is not secure.

After getting past that you can run functions specified by user input. In our testing it looks like you are limited to running functions in the MPSUM_Admin_Ajax class, so this wouldn’t necessarily be classified as remote code execution (RCE), but since anyone logged in to WordPress that has access to any valid nonce can run various functionality they are not intended to, it would at least be privilege escalation.

Some of the class’ functionality is further limited with a capabilities check, but others are not, as the proof of concept below for disabling automatic updates for a specified theme shows.

You could think that the explanation for having so poorly thought out code might be explained in part to do with the fact that it started life as very different plugin, as the slug for it is stops-core-theme-and-plugin-updates, which isn’t necessarily something you would expect someone familiar with security would be involved in, but it turns out the code being insecure was a recent situation, which looks to coincide with a premium version coming in to existence based on the changelog entries for the plugin.

The WordPress Tavern’s coverage of the plugin’s sale in January of last year, which preceded the code being vulnerable, included this line:

Without proper vetting, selling established plugins to individuals or companies can be harmful to sites and tarnish its reputation. Because UpdraftPlus is a well established company, Huereca didn’t have to do a lot of research.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Proof of Concept

The following proof of concept will disable automatic updates for the theme Twenty Nineteen, when logged in to WordPress. That can be confirmed on the page /wp-admin/index.php?page=mpsum-update-options&tab=themes.

Make sure to replace “[path to WordPress]” with the location of WordPress and “[heartbeat nonce]” with the value right after ‘var heartbeatSettings = {“nonce”:”‘ in the source code of admin pages.

<form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=eum_ajax" method="POST">
<input type="hidden" name="nonce_key" value="heartbeat-nonce" />
<input type="hidden" name="nonce" value="[heartbeat nonce]" />
<input type="hidden" name="subaction" value="save_themes_update_options" />
<input type="hidden" name="data[themes][twentynineteen]" value="false" />
<input type="submit" value="Submit" />

Concerned About The Security of the Plugins You Use?

When you are a paying customer of our service, you can suggest/vote for the WordPress plugins you use to receive a security review from us. You can start using the service for free when you sign up now. We also offer security reviews of WordPress plugins as a separate service.