Cross-Site Request Forgery (CSRF)/PHP Object Injection Vulnerability in Shoppable Images Lite
Back in June we introduced a new feature to our service where we are trying to proactively catch some serious vulnerabilities in WordPress plugins. The original idea was to catch vulnerabilities as they are newly introduced to the plugin, but when we started working on doing that we realized that it would also catch existing vulnerabilities if they were in code being changed in a plugin. At the end of August, for the first time we caught a serious vulnerability as it was introduced in to a plugin. For the second instance of that occurring, which happened the next week, not only did we catch a vulnerability as it was introduced, but with the first version of the plugin. That should be a good reminder that the review done before a plugin is allowed in to the Plugin Directory does not insure that the plugin is secure at the time it is introduced.
The vulnerability is a cross-site request forgery (CSRF)/PHP object injection vulnerability in the plugin Shoppable Images Lite.
In the first version of the plugin, when visiting the plugin’s settings page in the admin area of WordPress, which is accessible to users with the “manage_options” capability, the function show_admin_notices() would run. Here is that function, from the file /core/common/class-admin.php:
public function show_admin_notices() { $notices = self::$notices; foreach( $notices as $notice ) { echo '>div class="notice is-dismissible notice-'.$notice['class'].'">>p>'.$notice['message'].'>/p>>/div>'; } if(isset($_GET['notice']) && isset($_GET['page']) && $_GET['page'] === Config_Manager::$slug){ $notice = unserialize(base64_decode($_GET['notice'])); echo '>div class="notice is-dismissible notice-'.$notice['class'].'">>p>'.$notice['message'].'>/p>>/div>'; } }
If the GET input “notice” exists the value of it will be unserialized, which permits PHP object injection.
If an attacker could get someone with the “manage_options” capability, which is normally only Administrators, to visit a specified URL they could cause that user to unintentionally cause PHP object injection to occur.
It also looks possible for there to be reflected cross-site scripting (XSS) due to the GET input being echo’d, but in a quick look we ran into issues with serialization/unserialization of HTML tags.
After we notified the developer they released version 1.0.1, which fixed the vulnerability by removing the function show_admin_notices().
Proof of Concept
With our plugin for testing for PHP object injection installed and activated, the following proof of concept will cause the message “PHP object injection has occurred.” to be shown, when logged in as an Administrator.
Make sure to replace “[path to WordPress]” with the location of WordPress.
http://[path to WordPress]/wp-admin/options-general.php?page=mabel-shoppable-images-lite¬ice=TzoyMDoicGhwX29iamVjdF9pbmplY3Rpb24iOjA6e30%3D
Timeline
- September 5, 2017 – Developer notified.
- September 6, 2017 – Developer responds.
- September 23, 2017 – Version 1.0.1 released.