22 Nov

Authenticated Arbitrary File Upload Vulnerability in Vmax Project Manager

A month ago we wrote about how the security review of newly submitted plugins to the WordPress Plugin Directory needs improvement. One of the newly introduced plugins that lead to that was the plugin Vmax Project Manager. We came across the plugin through our proactive monitoring of changes made to plugins to try to catch serious vulnerabilities, due to the possibility of an arbitrary file upload vulnerability in the plugin.

What got flagged during our monitoring was the following line in the file /model/function.php:
move_uploaded_file($_FILES['file_name']['tmp_name'], $upload_dir['basedir'] . '/vpm/project_file/' . $_FILES["file_name"]["name"]);

That alone doesn’t tell you much, as all you can tell is it looks like an uploaded file is being saved to the filesystem with its filename intact.

With the fuller context of the function it is in you can see that there are no checks being done there that might restrict what types of files might be uploaded:

function vpm_file_create() {
	$data['vpm_project_id']	=	sanitize_text_field($_POST['vpm_project_id']);
	$data['file_name']		=	$_FILES['file_name']['name'];
	$data['note']			=	sanitize_text_field($_POST['note']);
	$upload_dir = wp_upload_dir();
    move_uploaded_file($_FILES['file_name']['tmp_name'], $upload_dir['basedir'] . '/vpm/project_file/' . $_FILES["file_name"]["name"]);

There still could be code elsewhere that restricts what type of files can be uploaded, though more often than not the code doing any checks would be in that.

That still doesn’t mean there is a vulnerability as the code still needs to be accessible in a way that it can be abused.

That function is called in one place, in the file /controller/controller.php:

	else if($task	==	'create_file') {

That value of $task comes from the beginning of the file, which also checks for a valid nonce:

$nonce 	=	sanitize_text_field($_POST['nonce']);
$task 	=	sanitize_text_field($_POST['task']);
$nonce_verify	=	wp_verify_nonce($nonce , 'vpm-project-manager');
// Only if nonce values submitted with post calls are verified, those db query functions will be executed
if ($nonce_verify == true) {

At that point we went to look at the issue from inside WordPress, though we later went to back to tracing the code used and spotted another vulnerability in the plugin, which will be the subject of another post.

On the plugins’ page to manage a project there is a section for files:

That page is available to anyone with the “read” capability, which is a capability that provides access to Admin dashboard and is a capability provided to Subscriber-level users and above (in the file /vpm.php):

$menu = add_menu_page('Vpm Project Manager', 'Project Manager', 'read', 'vpm-project', 'vpm_project' );

When you click Create you are taken to a page to upload a file:

If you try to upload a file with a .php extension that is not stopped:

So anyone that is logged in to WordPress with the “read” capability can upload arbitrary files.

We notified the developer of the issue on October 18. They responded five days later and said that it would be fixed within two weeks, but so far no new version of the plugin has been released. In line with our disclosure policy, which is based on the need to provide our customers with information on vulnerabilities on a timely basis, we are now disclosing this vulnerability.


  • October 18, 2017 – Developer notified.
  • October 23, 2017 – Developer responds.

Concerned About The Security of the Plugins You Use?

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