Our Proactive Monitoring Caught a CSRF/Arbitrary File Upload Vulnerability in a WordPress Security Plugin
When it comes to WordPress security plugins, not only do they often not provide much, if any, security against threats that really impact a website, but they can actually introduce security vulnerabilities of their own. That is the case with the plugin LionScripts: IP Blocker Lite, which is described as:
LionScripts IP Blocker for WordPress allows you to block the malicious IP Addresses, Spammers and Hackers
Through our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities we caught an arbitrary file upload vulnerability that could be exploited through cross-site request forgery (CSRF) in the plugin, which the IP blocking it provides wouldn’t impact since the attack request sent to the website comes from a logged in Administrator.
The vulnerability has gone unnoticed in the plugin for over six years.
In not a great sign of the quality of the plugin when registering its admin page “IP Address Blocker” it still uses a user level instead of a role or capability:
162 | add_submenu_page( strtolower(LIONSCRIPTS_SITE_NAME_SHORT), $this->plg_short_name, $this->plg_name, 'level_8', $this->site_admin_url_val, array($this, 'lionscripts_plg_f') ); |
Those were deprecated in WordPress 3.0, which was released in June, 2010. The first version of the plugin was introduced in October, 2012, which makes usage of user levels seem more out of place.
The user level used limits access to users with the Administrator role.
Accessing that page will cause the function lionscripts_plg_f(), which is located in the file /lib/lionscripts_plg_wib.class.php, to run. Code near the beginning of that will cause the function wib_uploader() to run if there is POST input and the GET input “block_type” is set to “upload”:
272 273 274 275 276 277 278 279 280 281 282 283 284 | public function lionscripts_plg_f() { global $LIONSCRIPTS; $this->print_admin_styles(); $this->use_thickbox(); if($_POST) { $blocked_ips_list = $this->get_all_blocked_ips(); if(isset($_GET['block_type']) && ($_GET['block_type'] == 'upload')) { $uploaded_ips_csv = $this->wib_uploader('input_ips_csv_upload_lite'); |
That function, in the same file, will upload a file sent with the request to the current month’s upload directory:
568 569 570 571 572 573 574 575 | public function wib_uploader($f_name) { $upload_dir = wp_upload_dir(); $path = $upload_dir_path = $upload_dir['path']; if( isset($_FILES[$f_name]) && ($_FILES[$f_name] != '') && !($_FILES[$f_name]["error"] > 0) ) { $file_name = $_FILES[$f_name]["name"]; move_uploaded_file($_FILES[$f_name]["tmp_name"], $path.'/'.$file_name); |
Despite the frontend for that upload functionality restricting it so that only .csv files can be uploaded the backend code doesn’t impose that restriction and doesn’t include a check for a valid nonce to prevent CSRF, so an attacker could cause a logged in Administrator to upload malicious .php files.
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 place the uploaded file in to the upload directory for the current month, 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=lionscripts-ip-address-blocker&block_type=upload" method="POST" enctype="multipart/form-data"> <input type="file" name="input_ips_csv_upload_lite" /> <input type="submit" name="submit" value="Submit" /> </form> </body> </html>