27 Oct

Restricted File Upload Vulnerability in Social Articles

Back in June and July we ran into an odd situation where there was supposed to have been a vulnerability fixed in the plugin WP Job Manager, but what is supposed to be the issue was still possible with the plugin. That supposed issue involved some form of abuse of the plugin’s image upload capability, but the change made simply restricted uploading images through WordPress’ AJAX functionality when not logged in to WordPress, but by default those not already with WordPress accounts on the website can still upload images files. The developer’s explanation for the action they took doesn’t really make sense, but out of this it did provide an indication that people with bad intentions will abuse the ability to upload image files. That capability to upload image files could also be used in conjunction with a local file inclusion (LFI) vulnerability, so making sure that those that are not intended to upload image files can’t upload them is a good idea.

All that brings us to the plugin Social Articles, which came on to our radar because code in it was noticed during our proactive monitoring of changes made to plugins to try to catch serious vulnerabilities. That picked up the possibility that there was an arbitrary file upload vulnerability in the plugin. When we went to look into that we found the plugin’s code would restrict files that could be uploaded to ones that had one of the following image extensions: gif, jpeg, jpg, or png. So there wasn’t an arbitrary file upload vulnerability, but in looking in to that we found that the plugin was allowing people not intended to upload files to do that.

The plugin works with the plugin BuddyPress and allows users to create articles from their profile and therefore functionality like uploading images is only intended to done by logged in users. But to use the upload capability as an example, it is handled through WordPress’ AJAX functionality and was available to anyone, even if they are not logged in, due to registering it with the both the wp_ajax_ and wp_ajax_nopriv_ actions:

add_action('wp_ajax_nopriv_image_uploader', array(&$this, 'image_uploader'));
add_action('wp_ajax_image_uploader', array(&$this, 'image_uploader'));

The  wp_ajax_nopriv_ one allows those not logged to access it.

The function didn’t provide any check to limit who can access it:

public function image_uploader ()
	$uploads = wp_upload_dir();
	if (!class_exists('qqFileUploader')) require_once(SA_BASE_PATH.'/includes/sa-form/fields/commons/uploader.php');
	$uploader = new qqFileUploader(array('jpg', 'jpeg', 'png', 'gif'));
	$result = $uploader->handleUpload($uploads['basedir'].'/');
	echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);

It does limit what types of files can be uploaded, as we mentioned before.

That function and others in the plugin also lack protection against cross-site request forgery (CSRF).

After we notified the developer they released version 2.5, which fixes the issue by removing the wp_ajax_nopriv_ action and adding a check for a valid nonce before allowing an upload (and adding a related nonce to the request to be sent to upload an image):

public function image_uploader ()
	check_ajax_referer( 'sa_security_ajax', 'security');

Proof of Concept

The following proof of concept will upload the selected file with a gif, jpeg, jpg, or png to the directory /wp-content/uploads/.

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

<form action="http://[path to WordPress]/wp-admin/admin-ajax.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="image_uploader" />
<input type="file" name="qqfile" />
<input type="submit" value="Submit" />


  • October 19, 2017 – Developer notified.
  • October 19, 2017 – Developer responds.
  • October 26, 2017 – Version 2.5 released, which fixes vulnerability.

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.