30 Jan

Our Proactive Monitoring Caught an Authenticated Arbitrary File Upload Vulnerability in Events Made Easy

Yesterday we disclosed an arbitrary file upload related vulnerability discovered through our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities for which the underlying vulnerable code ran despite the user interface for it being disabled. That turns out to not be a one-off issue as our proactive monitoring has also led to us finding an authenticated arbitrary file upload vulnerability in the plugin Events Made Easy where the user interface also appears to be missing. This is a good reminder of the limits of trying to look for vulnerabilities without looking at the underlying code of software.

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.

Technical Details

By default WordPress users with the Contributor role and above can access the plugin’s functionality to add or update a person, /wp-admin/admin.php?page=eme-people. That provides the option to set an image for the person:

Clicking on that button brings up WordPress’ media uploader:

That has restrictions on what can be uploaded (and contributor level users would normally not be allowed to do uploads through that at all).

When a request to add or update a person is submitted the function eme_add_update_person() in the file /eme_people.php is run. That in turn will cause the function eme_upload_files() in the file /eme_functions.php to run.

When that function runs it will save files sent with the request to the file system using its own code instead of the code used when using the media uploader.

The code does attempt to restrict what types of files can be uploaded, but that can easily be bypassed.

First the code defines the variable $supported_mime_types to include the mime types returned by the WordPress function wp_get_mime_types():

1843
$supported_mime_types = wp_get_mime_types();

In then checks if the mime type of the file being uploaded is one of the mime types specified previously:

1920
1921
1922
1923
if (!in_array(mime_content_type($temp_name),$supported_mime_types)) {
	$errors[] = $fileName.': '.__("Incorrect file type.","events-made-easy");
	continue;
}

The problem with that is you can upload a file with a .php extension containing malicious PHP code that passes that check by simply having the start of the file be “GIF89a”, as that causes the mime type to be seen as a permitted one.

The uploaded file is given a randomized named, but a link to file is included on update user page if you uploaded the file through an existing user.

Proof of Concept

When accessing the page of an existing user, use a web browser’s developer tools to edit the HTML code of the page to add the following line to the form for updating the user:

<input type="file" name="FIELD1_1" />

Then upload a file with the .php extension that begins “GIF89a”.

After the submitting the page, go back to it and the location of the file on server will be linked to.


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.

Leave a Reply

Your email address will not be published. Required fields are marked *