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>