3 Aug 2021

Wordfence Advisory Fails to Warn That WordPress Plugin with 100,000+ Installs Is Currently Very Insecure

As part of monitoring we do to make sure we are providing customers of our service with the best possible data on vulnerabilities in WordPress plugins they may use, we monitor for what look to be hackers probing for usage of plugins to make sure we can quickly warn our customers of any unfixed vulnerabilities that hackers are likely targeting. On Sunday we had what looked to be a hacker probing for usage of the WordPress plugin WordPress Download Manager, which has 100,000+ active installation according to wordpress.org, on our website with this request:

/wp-content/plugins/download-manager/readme.txt

That could indicate that the plugin contains or contained a vulnerability that hackers would be interested in exploiting.

Back in May there was a security change made to the plugin:

Fixed an security issue with link/page template file path, thanks for Wordfence for pointing the issue.

But that doesn’t look like an issue that hackers would actually be likely to exploit because of the access required. Despite that, it might be what the hacker was looking to access, though possibly not understanding the limitation there, as on Thursday, the Wordfence referenced there, published a post on the vulnerability. We have frequently seen hackers quickly turn around from them disclosing vulnerabilities to trying to exploit them (despite Wordfence claiming that their providing limited details somehow helps to limit that).

Since that seems unlikely to actually be exploited, we went to check on the plugin to see if there might be something else a hacker might target. What we found was that plugin is currently very insecure and the security code is quite a mess. That is something that Wordfence didn’t note. That stands out since for the two things that end their post, the first is this:

Nonetheless, if you know a friend or colleague who is using this plugin on their site, we highly recommend forwarding this advisory to them to ensure their site has been updated.

That is bad advice, as an important take away here would be the importance of keeping your plugins up to date at all times, especially as the advisory is coming months after the update was released. Wordfence should be well aware of the need to keep plugins up to date at all times, but saying that would get in the way of promoting their service, which they know doesn’t provide better protection for fixed vulnerabilities than keeping plugins up to date. The real reason they want you to forward the advisory is for marketing purposes, which makes the whole thing worse.

The last thing is this:

Special thanks to the developer of the WordPress Download Manager plugin, W3 Eden, for their excellent and timely response.

A developer having insecure code and fixing it when informed of an issue isn’t necessarily something they should be thanked for, but when the plugin is very insecure that seems inappropriate. It wouldn’t have been hard for Wordfence to know that, as here is one possible security issues flagged by an automated tool, our Plugin Security Checker, currently in the plugin:

User input is being directly output, which could lead to reflected cross-site scripting (XSS). File: /download-manager/src/Admin/views/templates/email-template-editor.php Code: 158 jQuery('#preview').html("<iframe style='width:100%;height:700px;border:0;' src='edit.php?action=email_template_preview&id=<?php echo $_GET['id']; ?>'></iframe>");

Outputting user input like that is something that the Wordfence should be well aware is insecure.

One of the other glaring security issues with the code is that it erratically applies various basic security checks and does them in different ways, sometimes in the same place. Based on that, this plugin shouldn’t be used at least until it has been through a proper security review and all the issues are resolved.

Take this function where the first code in it twice checks for a valid nonce, which prevents cross-site request forgery (CSRF):

329
330
331
332
333
function deleteItem()
{
 
	if (!isset($_REQUEST['__wpdm_unlink']) || !wp_verify_nonce($_REQUEST['__wpdm_unlink'], WPDMAM_NONCE_KEY)) wp_send_json(array('success' => false, 'message' => __("Error! Session Expired. Try refreshing page.", "download-manager")));
	check_ajax_referer(WPDMAM_NONCE_KEY, '__wpdm_unlink');

Doing that twice doesn’t appear to serve any purpose there.

At the same time that protection is missing elsewhere. Here is one example of that protection missing that then also looks to involve SQL injection as unsanitized/unvalidated user input is introduced in to an unprepared SQL statement:

120
121
122
123
124
125
126
127
128
129
130
131
function deleteEmails()
{
	global $wpdb;
	if (!current_user_can(WPDM_ADMIN_CAP)) return;
	$task = isset($_GET['task']) ? $_GET['task'] : '';
	$page = isset($_GET['page']) ? $_GET['page'] : '';
	if ($task == 'delete' && $page == 'wpdm-subscribers') {
		$ids = implode(",", $_POST['id']);
		if (wpdm_query_var('lockOption') == 'email' || wpdm_query_var('lockOption') == '')
			$wpdb->query("delete from {$wpdb->prefix}ahm_emails where id in ($ids)");
		else
			$wpdb->query("delete from {$wpdb->prefix}ahm_social_conns where ID in ($ids)");

That code at least includes a capabilities check, which isn’t the case elsewhere.

Authenticated Settings Change Vulnerability

In the file /src/Admin/Menu/Templates.php various functions are made accessible thorugh WordPress’ AJAX functionality to those logged in including a function to save email settings:

22
add_action('wp_ajax_wpdm_save_email_setting', array($this, 'saveEmailSetting'))

That function doesn’t include a nonce check or a capabilities check:

268
269
270
271
272
273
function saveEmailSetting(){
	update_option('__wpdm_email_template', wpdm_query_var('__wpdm_email_template'), false);
	$email_settings = wpdm_query_var('__wpdm_email_setting', array('validate' => array('logo' => 'url', 'banner' => 'url', 'youtube' => 'url', 'twitter' => 'url', 'facebook' => 'url', 'footer_text' => 'txts')));
	update_option('__wpdm_email_setting', $email_settings, false);
	die("Done!");
}

So anyone logged in to WordPress can change the settings. At least there is sanitization happening, so unless that could be evaded, that code doesn’t look to permit cross-site scripting (XSS) to occur.

WordPress Causes Full Disclosure

Because of the moderators of the WordPress Support Forum’s continued inappropriate behavior we changed from reasonably disclosing to full disclosing vulnerabilities for plugins in the WordPress Plugin Directory in protest, until WordPress gets that situation cleaned up, so we are releasing this post and then leaving a message about that for the developer through the WordPress Support Forum. (For plugins that are also in the ClassicPress Plugin Directory, we will follow our reasonable disclosure policy.) 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, but considering that they believe that having plugins, which have millions installs, remain in the Plugin Directory despite them knowing they are vulnerable is “appropriate action”, something is very amiss with them (which is even more reason the moderation needs to be cleaned up).

Update: To clear up the confusion where developers claim we hadn’t tried to notify them through the Support Forum (while at the same time moderators are complaining about us doing just that), here is the message we left for this vulnerability:

Is It Fixed?

If you are reading this post down the road the best way to find out if this vulnerability or other WordPress plugin vulnerabilities in plugins you use have been fixed is to sign up for our service, since what we uniquely do when it comes to that type of data is to test to see if vulnerabilities have really been fixed. Relying on the developer’s information can lead you astray, as we often find that they believe they have fixed vulnerabilities, but have failed to do that.

Proof of Concept

The following proof of concept will change the Footer Text setting, which can be seen on the page /wp-admin/edit.php?post_type=wpdmpro&page=templates&_type=email, to “proof of concept”, when logged in to WordPress.

Replace “[path to WordPress]” with the location of WordPress.

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=wpdm_save_email_setting" method="POST">
<input type="hidden" name="__wpdm_email_setting[footer_text]" value="proof of concept" />
<input type="submit" value="Submit" />
</form>
</body>

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.

Leave a Reply

Your email address will not be published.