Automattic is Having WooCommerce Install by Default an Insecure Plugin by Facebook
The line between the open source project WordPress and the company Automattic is often blurry. You can find journalists referring to the latter as owning the former, despite that not being true. The person who resigned a couple of week as the Marketing and Communications Lead for WordPress mentioned that they were often assumed to be an Automattic employee or as the token non-Automattic team member:
My position is unclear, not just to me, but to many people which makes me uncomfortable. I’ve been asked dozens of times on Twitter, Facebook and at WordCamps why I now work for Automattic, which of course I don’t but that is the perception for a lot of people. On other occasions I seem to be the token non-Automattician, which I’m also uncomfortable with.
Something we happened across involving Automattic is a reminder that their influence isn’t necessarily going to produce good security results and might help to explain the lack of interest or commitment to security by the person in charge of WordPress, Matt Mullenweg, considering he is also in charge of Automattic.
Automattic is behind the very popular ecommerce plugin WooCommerce, which has 4+ million installs. When running the set up wizard for that there are a number of additional plugins are installed by default. Among the plugins “Recommended for All WooCommerce Stores”, which are installed by default is Facebook for WooCommerce:
Recently we have been thinking about security vulnerabilities connected to WooCommerce due to things like it appearing that hackers are discovering and targeting vulnerabilities in plugins that work with it.
While working on something else, we ran across the website wptrends.net, which uses data from wordpress.org to calculate the growth of plugins. Facebook for WooCommerce is currently listed fifth on that for growth in installs in the last four weeks and had growth of +47.60%. That seems to be in large part due to WooCommerce installing it by default. As that started being done in a version of WooCommerce released on April 17 and the chart of downloads for Facebook for WooCommerce shows that there was a sustained increase of downloads starting then:
The plugin currently has 200,000+ active installations according to stats provided by WordPress.
If you go to the plugin’s page on the WordPress Plugin Directory the first thing you likely will notice is the warning message “This plugin hasn’t been tested with the latest 3 major releases of WordPress. It may no longer be maintained or supported and may have compatibility issues when used with more recent versions of WordPress.”:
It seems odd that Automattic would be recommending, much less installing by default, a plugin that isn’t being maintained enough to update the compatibility. That is odder still when you consider that the first version of Facebook for WooCommerce was submitted to the directory on February 22, nearly two months after WordPress 5.0 was released, yet it wasn’t listed as being compatible with that version at that time or subsequently. The plugin is also only listed as being tested up to version 3.3.5 of WooCommerce, which was superseded in May of last year.
After noticing that warning we went to do a quick check of the plugin’s security and immediately ran across a vulnerability due to rather basic security failure, though there are other security checks in place that limit the impact of that failure. It is hard for us to understand how Automattic thought it would be a good idea to cause this to be installed on a lot of website without first doing a quick glance over the security of the plugin. (If they don’t have the capability to do that we offer a service to do just that.)
Cross-Site Request Forgery (CSRF)/Option Update
When we started looking over the plugin’s settings page what we noticed was that a nonce was not being sent with an AJAX requests from that, which is needed to prevent cross-site request forgery (CSRF). Looking at the underlying code we found that. at least, many of the AJAX accessible functions lack that. One such example is the function ajax_update_fb_option().
That function is registered to accessible to anyone logged in to WordPress through its AJAX functionality in the file /facebook-commerce.php:
217 218 | add_action('wp_ajax_ajax_update_fb_option', array($this, 'ajax_update_fb_option'), self::FB_PRIORITY_MID); |
Later in the same file is the function itself:
2531 2532 2533 2534 2535 2536 2537 | function ajax_update_fb_option() { WC_Facebookcommerce_Utils::check_woo_ajax_permissions('update fb options', true); if (isset($_POST) && stripos($_POST['option'], 'fb_') === 0) { update_option(sanitize_text_field($_POST['option']), sanitize_text_field($_POST['option_value'])); } wp_die(); } |
The first code in the calls the function check_woo_ajax_permissions(), which is located in the file /includes/fbutils.php, and restricts access to the rest of the code to those with the “manage_woocommerce” capability:
278 279 280 281 282 283 284 285 286 287 288 289 290 | public static function check_woo_ajax_permissions($action_text, $die) { if (!current_user_can('manage_woocommerce')) { self::log( 'Non manage_woocommerce user attempting to'.$action_text.'!', array(), true); if ($die) { wp_die(); } return false; } return true; } |
The rest of the code there allows updating and WordPress option (setting) that stats “fb_”. The value is sanitized using sanitize_text_field(), which limits placing malicious JavaScript code as the settings value.
What is noticeable absent though is a check for a valid nonce to prevent cross-site request forgery (CSRF), so it would be possible for an attacker to cause someone logged with the “manage_woocommerce” capability to make changes to options without intending it.
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 create a WordPress option named “fb_vulnerable” with the value “yes”, when logged in as a WordPress user with the “manage_woocommerce” capability. That can be confirmed by looking at the underlying _options table.
Make sure to replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=ajax_update_fb_option" method="POST"> <input type="hidden" name="option" value="fb_vulnerable"> <input type="hidden" name="option_value" value="yes"> <input type="submit" value="Submit" /> </form> </body> </html>