Automattic Reintroduced Security Vulnerability Into WooCommerce, Their WPScan Missed That
Automattic is the company from the head of WordPress, Matt Mullenweg. Among its operations, it sells access to (often inaccurate) information on vulnerabilities in WordPress plugins through WPScan. Earlier this week WPScan added an entry for a claimed vulnerability in Automattic’s WooCommerce plugin, which has 5+ million installs according to WordPress’ data. They claimed the vulnerability had been fixed in version 7.0.1:
That version was released on November 1, 2022.
In checking in to this, we found there really was a vulnerability. Unfortunately, we also found that it exists in the latest version of WooCommerce.
Partial Disclosure
As at least one of our customers uses WooCommerce, we went to check on WPScan’s claim once we ran across it. We didn’t have a record for the claimed vulnerability already, which is a bit odd since we should have already looked into this if it had been mentioned in the changelog for the plugin, as we check security related entries from those for plugins used by our customers. Looking at the changelog for the version that it was claimed this was fixed in, we found there was no mention of a security fix:
* Dev – Twenty Twenty-Three theme compatibility. [#35306](https://github.com/woocommerce/woocommerce/pull/35306)
* Dev – Simplify and reduce size of payload supplied by the woocommerce_get_customer_details ajax endpoint.
Both changes are labeled as “dev”, while the changelog has 50 entries labeled as “security”. This being the most recent entry labeled as “security” (this will become relevant in a bit):
* Security – Customers REST API endpoint will now return user metadata only when requester has an administrator role [#36408](https://github.com/woocommerce/woocommerce/pull/36408).
After looking into this further, we did find they acknowledged there was a security fix in a blog post announcing the release of the new version:
Simplify and reduce size of payload supplied by the woocommerce_get_customer_details ajax endpoint which addresses a security concern relating to handling of user information that is exploitable by shop managers and above. Thanks for highlighting this David Anderson.
The David Anderson referenced there left this comment on the blog post:
This is to say, previous versions of WooCommerce contain an information leaking vulnerability. A user with “shop manager” privileges can gain access to information that would not normally be accessible to anyone below the “administrator” level. Specifically, such a user can obtain access to all contents of the WordPress “usermeta” table. Potentially this could include secret keys, API keys or other sensitive data, depending on what plugins are in use on the site.
So, if your site has shop managers who are not administrators, then you are vulnerable, and should upgrade as soon as possible.
I was expecting Automattic to publish this information for the benefit of store owners with much more clarity than the above. Without specific information, it is hard for store owners to know how urgent upgrading may or may not be for them.
The Vulnerable Code
The vulnerable code consisted of the AJAX accessible function get_customer_details() in the file /includes/class-wc-ajax.php. The change in version 7.0.1 was to add this line to the function:
887 | unset( $data['meta_data'] ); |
The fuller code of the function as of version 7.0.1 was:
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 | public static function get_customer_details() { check_ajax_referer( 'get-customer-details', 'security' ); if ( ! current_user_can( 'edit_shop_orders' ) || ! isset( $_POST['user_id'] ) ) { wp_die( -1 ); } $user_id = absint( $_POST['user_id'] ); $customer = new WC_Customer( $user_id ); if ( has_filter( 'woocommerce_found_customer_details' ) ) { wc_deprecated_function( 'The woocommerce_found_customer_details filter', '3.0', 'woocommerce_ajax_get_customer_details' ); } $data = $customer->get_data(); $data['date_created'] = $data['date_created'] ? $data['date_created']->getTimestamp() : null; $data['date_modified'] = $data['date_modified'] ? $data['date_modified']->getTimestamp() : null; unset( $data['meta_data'] ); $customer_data = apply_filters( 'woocommerce_ajax_get_customer_details', $data, $customer, $user_id ); wp_send_json( $customer_data ); |
That new line removed user metadata returned by calling $customer->get_data() earlier in the code, before the user data is output.
Vulnerability Reintroduced
As part of our process of adding vulnerabilities to our data set, we try to make sure that there are no other similar issues still in the plugin. Often there are. In looking into this, we found similar code elsewhere. What we found was concerning, as the other instance was more secure. REST API accessible function prepare_item_for_response() in the file /includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php doesn’t pass all the data from $customer->get_data():
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | public function prepare_item_for_response( $user_data, $request ) { $customer = new WC_Customer( $user_data->ID ); $_data = $customer->get_data(); $last_order = wc_get_customer_last_order( $customer->get_id() ); $format_date = array( 'date_created', 'date_modified' ); // Format date values. foreach ( $format_date as $key ) { $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; // v1 API used UTC. } $data = array( 'id' => $_data['id'], 'date_created' => $_data['date_created'], 'date_modified' => $_data['date_modified'], 'email' => $_data['email'], 'first_name' => $_data['first_name'], 'last_name' => $_data['last_name'], 'username' => $_data['username'], 'last_order' => array( 'id' => is_object( $last_order ) ? $last_order->get_id() : null, 'date' => is_object( $last_order ) ? wc_rest_prepare_date_response( $last_order->get_date_created() ) : null, // v1 API used UTC. ), 'orders_count' => $customer->get_order_count(), 'total_spent' => $customer->get_total_spent(), 'avatar_url' => $customer->get_avatar_url(), 'billing' => $_data['billing'], 'shipping' => $_data['shipping'], ); |
560 | return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); |
Instead, it only allows some specified information to be output.
We then went to check on how the previously vulnerable function looked in the latest version, as it might have been further restricted as well, instead we found that the fix had been removed. Further checking showed that the fix had been removed in version 7.2.0, which was released on December 14, 2022. We also found that the user metadata is still being output as of the latest version of the plugin, 8.1.0.
A possible explanation for the fix disappearing is that it was never applied to the copy of the plugin in the plugin’s GitHub project.
The changelog entry for a security fix we mentioned before seems to confirm that as of two months after that change was undone, Automattic still believed allowing users with the shop manager role to have access to user metadata was a security issue:
The
wc/v3/customers and wc/v3/customers/<id>
REST API endpoints will now return user metadata only when the authentication credentials supplied correspond to an user that has the administrator role. Same for REST API v2 (v1 wasn’t returning user metadata already).
We notified Automattic’s security team earlier today that the vulnerability had returned.
WPScan Missed This
Going back to WPScan’s listing for this, it states:
The PoC will be displayed on September 25, 2023, to give users the time to update.
Based on what we already mentioned, there is an obvious problem with that, the vulnerability currently exists in the plugin. WPScan has missed that, despite it being something that experts should have caught. That doesn’t exactly line up with how Automattic markets WPScan:
It’s like having your own team of WordPress security experts.
With WPScan, you’ll be the first to know about vulnerabilities affecting your WordPress installation, plugins, and themes.
As we have noted in the past, when it comes to WPScan, knowing about vulnerabilities first isn’t all that useful if you are claiming that an unfixed vulnerability has been fixed. In most cases, WPScan are not even first either, despite that claim.
Plugin Security Scorecard Grade for WooCommerce
Checked on March 31, 2025See issues causing the plugin to get less than A+ grade