So, you own a Woocommerce store , and you were on a lookout for that one plugin that can help you in turning your website into a full-fledged online storefront. You installed Woocommerce but then you found out that your Woocommerce site is HACKED.
This hack could be due to various unpatched vulnerabilities present in WooCommerce. These can be in form of WooCommerce Checkout Payment Gateway plugin, a XSS vulnerability in cart plugin that allows remote injection of arbitrary web script, or, a design flaw in the WordPress permission system used by plugins. We will discuss all these WooCommerce Vulnerabilities hack in detail, how they affect your website & how to fix them and enhance ecommerce security.
In case you use Prestashop (a woocommerce alternative) you can go through our post on Prestashop Hacked – Vulnerabilities & Site Clean Up.
Let us move forward for more insights into WooCommerce plugin vulnerabilities 2024.
Table of Contents [TOC]
WooCommerce is a free plugin of WordPress. As we write, WooCommerce is powering more than 40 percent of the online businesses. It can be accessed from WooCommerce plugin directory, and you will gain the knowledge of all the basics of setting up an online business, selling physical or digital goods. Besides, the plugin can also help you in running affiliate sites, or it can be used to handle drop shopping for the printables and various other custom products.
Whether you are into selling a few products or a retail startup with plans to flourish your business, you can use WooCommerce to add all the important eCommerce features to your WordPress website.
Setting up and running your WooCommerce store along with a basic shared hosting plan is easy, but WooCommerce specific hosting will fuel, with features and support, your business and help build a brand.
The WooCommerce plugins comes with payment and shopping cart functions, and it also supports an extensive range of options using which can set up exclusive events, products, and landing pages.
WooCommerce plugin is one of the most famous & preferred WordPress plugins. This plugin serves commercial purposes well. What adds to the immense popularity of this plugin is the fact that it is flexible when it comes to customization options. On top of the built-in settings, developers, across the globe, have built a community around it and also created extensions.
Key Features –
All the websites, backed by a CMS platform, mostly use WordPress. Of late, the platform has entered the business arena with its eCommerce plugin known as WooCommerce. With the rising popularity of the platform, it has become more comfortable for hackers to infringe cyber boundaries.
This, understandably, makes a beginner precarious about the authenticity of the platform to host an eCommerce checkout solution. At this point, let us get to know how a WooCommerce website can get hacked.
We live in a time where the threat to the security of the consumer has emerged as one of the key issues that have plagued the businesses across the globe. It has become easier than ever for hackers to hack websites, mainly the ones that are hosted by WordPress.
These hackers gain illegitimate access to these websites, and they carry out checkout data theft, host malicious content, and cause significant losses to the eCommerce businesses during the checkout process.
Related Post – WordPress Privilege Escalation Vulnerability [Contact Form 7 & WP GDPR]
Hackers use some of the creative and illegitimate methods when it comes to hacking WordPress and WooCommerce websites. While there are no apparent signs of making out whether your website is hacked or not, tracing some of the common WordPress hacked signs will help. Following are some of the common signs –
Related Post – Common WordPress Security Vulnerabilities
With over 4 million installations, WooCommerce is, undoubtedly, one of the foremost eCommerce plugins. Since the plugin efficiently handles the customer payments, it is an easy target for the hackers, the websites supported by the plugin mainly stores customer’s personal and payment details.
Besides, being one of the popular eCommerce plugins, it is also one of the most vulnerable plugins as well. Some of the common vulnerabilities in the core WooCommerce plugin are –
Now, let us discuss the vulnerabilities mentioned above in detail.
Related Post – WordPress Security Checklist Guide
Topping the list is XSS (Cross-Site Scripting). WooCommerce plugin is susceptible to a cross-site scripting vulnerability. The key reason behind this is the inability to sterilize the input provided by the user aptly.
A hacker may take this opportunity to execute malicious script code in the browser of an unwary user. This will help the hacker offer free access to pilfer cookie-based confirmation credentials and initiate other attacks. If you are using WooCommerce plugin version 2.6.3 (previous versions as well), then you may be the victim of this vulnerability.
Further, Cross-Site Scripting is of two types –
This particular vulnerability occurs because the tax rates of WooCommerce has falsely processed the data provided to the victim user. The hacker, while sitting in a remote location, tend to outwit the WooCommerce administrators to upload malicious CSV file that supplies tax rate details for a particular nation or area.
This particular file further injects malicious code into the victim application, thus activating an XSS attack. Through this attack, the hacker easily gains full access to the webserver.
This vulnerability affects all WooCommerce versions before 2.6.9.
Related Post – WordPress Brute Force Attacks
For all WooCommerce users, the tax rate settings can be accessed from WooCommerce –> Settings –> Tax. You can set the tax rates in two ways –
Since every country and state has its tax rates, the majority of the shop managers look for the tax rate file and import it. This is clear from the image below.
Today, you can easily come across a website that offers either free or paid tax rate files. Following two images are carrying the examples of such websites. The hacker, who is sitting in a remote location, offering an infected CSV file, can deceive a WooCommerce administrator into downloading the file carrying the malicious code. All this will trigger the XSS attack.
State Code and Zip Code of the application code will have the vulnerability. Unfortunately, WooCommerce doesn’t disinfect the data provided by the user for state code and Zip Code leading to XSS vulnerability.
Let us understand this with the help of an example –
A hacker is capable of making changes to the Zip Code present in the CSV file and further set it to “. This can be seen in the image below.
As and when the hacker has installed the CSV file, this confirms that the XSS code has been successfully injected.
Once the user hovers the mouse over the ZIP code, the XSS code will be activated.
All WooCommerce users must upgrade to the latest version right away.
You can locate this particular XSS vulnerability, CVE-2019-9168, in the zoom display of Photoswipe function. This is where WooCommerce proved incompetent in disinfecting both the caption data and the title of the image.
As per this vulnerability, the hacker may be able to inject a random code into a website (powered by WooCommerce). The moment a user visits the page, carrying malicious code, the hacker instantly gains complete control of the user’s browser, seizes the ongoing WooCommerce session, and acquire the important information, etc. He could exploit this vulnerability to hijack the current user session, to gather sensitive data like banking information, addresses, etc.
This vulnerability affects WooCommerce versions before 2.6.9.
The WooCommerce team has issued a software patch. It is evident by their summary that WooCommerce now disinfects both the caption data and title. Have a look at the image below.
(You can see the steps visually in image given below)
To reproduce this vulnerability, uploading an image and inserting JavaScript into the caption field of the image will be your first step. In WordPress, if you are looking to upload an image into a low permission account, you don’t need a consent to access WooCommerce plugin.
The moment someone, having low permission privilege, adds this infected image as a product page or into the Product Gallery, the XSS code gets added into the product page.
At this stage, when the user views this product and zooms into the product image, this will automatically execute the XSS code.
The hacker could easily seize the ongoing session by exploiting this vulnerability. This will help in controlling the browser of the user and more. Since the targets are mainly eCommerce websites, the hacker could easily gain access to important information like addresses, banking details, etc.
Related Post –
It is imperative for the users of all vulnerable versions of WooCommerce plugin to upgrade to the latest version immediately.
As per research, a PHP Object Injection vulnerability in WooCommerce (CVE-2017-18356) was discovered that allows for escalating privileges using a unique injection method.
This type of vulnerability is mainly enjoyed by a hacker that already enjoys higher privileges. You need to have some ability to add/edit products in WooCommerce, but not a complete administration account that will let to execute the code anyway. This means that the attacker can use the vulnerability to escalate a previously realized attack or account takeover.
During runtime, if the hacker can successfully inject an arbitrary PHP object, then usually it results in an array of malicious actions. In the worst case, the hacker can easily perform an arbitrary code on the server and can gain access to the shop along with important data.
Before we go ahead understand the vulnerability, first we have to get familiar with two things –
The security release 4.8.3 of WordPress tackled this issue with prepare() method of wpdb. However, in some cases, it may lead to SQL injection.
The actual issue was with what happens when wpdb::prepare() is applied a couple of times. The following example explains this behavior –
$query = $wpdb->prepare( "SELECT * FROM table WHERE column1 = %s", $_GET['c1'] ); if( isset($_GET['c2']) ) { $query = $wpdb->prepare( $query . " AND column2 = %s", $_GET['c2'] ); } $wpdb->query( $query );
As both the values that originates from user input (c1 and c2) are bound through wpdb::prepare(), one is forced to believe that this is safe and it is impossible to inject SQL.
But, initially, in WordPress 4.8.2 wpdb::prepare() will quote the placeholders followed by the binding of the parameters with vsprintf(). With the help of the following example, let us understand what will happen if the user input is set as follows –
$_GET['c1'] = " %s "; $_GET['c2'] = [" OR 1=1 -- ", ""];
In the example mentioned above, the initial call to wpdb::prepare() will be adding quotes around the placeholder %s and escape the user input c1. But in this case, the placeholder %s gets substituted with the user input that again comprises of the placeholder %s. The $query will result in the following –
SELECT * FROM table WHERE column1 = ' %s ';
In the second call to wpdb::prepare(), the placeholders in the query (%s) will be quoted once again, this perplexes the quoting.
SELECT * FROM table WHERE column1 = ' '%s' ' AND column2 = '%s';
Lastly, as and when the values are bound with vstprintf(), the query will look like –
SELECT * FROM table WHERE column1 = ' ' OR 1=1 -- ' ' AND column2 = '';
As it is clearly visible that it leads to SQL injection vulnerability.
For WordPress 4.8.3, the fix for this issue is the replacement of each occurrence of the percent signs in wpdb::prepare() with a random 66 characters long placeholder following bounding of the values. Before the execution of the query, these placeholders will be replaced back to the percent signs.
Related Post – WordPress DDoS Attack – Tips To Protect & Secure Your Website
To have a better comprehension of the vulnerability, it is better to have a holistic knowledge of how the PHP interpreter turns the serialized data back to its respective type of data. For this, let us first examine the below-mentioned example representing a serialized object of type stdClass with two features – firstname and mail.
O:8:"stdClass":2:{s:9:"firstname";s:4:"rips";s:4:"mail";s:13:"rips@mail.com";}
Seeing the first character 0, the PHP interpreter is familiar with the fact that the object is being unserialized. In order to restore the state of the object, there are certain things you require –
Remaining data gets described as follows –
The key idea behind the exploitation method is shown using the following code sample –
class Object_Injection { public function __wakeup() { die( 'Object injected' ); } } $input_1 = 'abc_xxxxxxxxxxxxxxxxxxx_'; $input_2 = 'whatever";i:1;O:16:"Object_Injection":0:{}'; $a = array( $input_1, $input_2 ); $serialized = serialize( $a ) ; //a:2:{i:0;s:24:"abc_xxxxxxxxxxxxxxxxxxx_";i:1;s:42:"whatever";i:1;O:16:"Object_Injection":0:{}";} $serialized = preg_replace( '/\_[^\_]*\_/', '%', $serialized ); // critical modification $unserialized = unserialize( $serialized );
In line 12, a simple array having 2 elements of strings is serialized. When the content of $serialized is unserialized, this helps in bringing back the original collection. The main part of this example is that the regular expression in line 15 changes the serialized data.
It substitutes _xxxxxxxxxxxxxxxxxxx_ with %. The result is the following malformed serialized data –
a:2:{i:0;s:24:”abc%”;i:1;s:42:”whatever”;i:1;O:16:”Object_Injection”:0:{}”;}
The vulnerable code in WooCommerce is in WC_Shortcode_Products::get_products().
woocommerce/includes/shortcodes/class-wc-shortcode-products.php
protected function get_products() { $transient_name = ...; $products = get_transient( $transient_name ); if ( false === $products || ! is_a( $products, 'WP_Query' ) ) { ⋮ $products = new WP_Query( $this->query_args ); ⋮ 9 set_transient( $transient_name, $products, DAY_IN_SECONDS * 30 ); } ⋮ return $products; }
Set transient() is one of WordPress’s functions and it is mainly used for caching (as seen in line 10). It tends to save given data for a set period of time in the database. In a situation where the data is an array or an object, it will be serialized.
In the later stages, the data can be recovered using get transient() which is responsible for deserializing it (as seen in line 3). To cache the WP_Query object, the developers use this method, which is created in line 7 to save the sources.
In addition to having content of the retrieved posts/products, the $request feature is there in the WP_Query object. This particular feature comprises of the SQL query that was performed to recover the posts.
The SQL query is made using numerous arguments passed to WP_Query and still has 66 characters longs placeholders. The moment set_transient()saves the object to the database; these placeholders are removed following by the serialization of the object.
So, if a hacker manages to add a percentage sign into the $request feature, they will be 66 characters long placeholders at the moment of serialization of the object. However, this will be replaced backed to one character once the serialized string gets saved to the database. Let us have a look at how this is done.
The inclusion of WooCommerce shortcode [products skus=”testsku, test%%”], either to a post or a page, will lead to a WP_Query object having the following $request feature that needs to be serialized and cached in WC_Shortcode_Products::get_products().
SELECT wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) WHERE 1=1 AND (
⋮ AND ( ( wp_postmeta.meta_key = '_sku' AND wp_postmeta.meta_value IN ('testsku','test{9016c2295825bd198c342af50fd2da2e4a1f72f2f23ab4ea5f381c41b99440ba}{9016c2295825bd198c342af50fd2da2e4a1f72f2f23ab4ea5f381c41b99440ba}') ) AND ⋮
Have a closer look at how test%% was converted with placeholders to test{9016c22…}{9016c22…}. This is where the serialized object gets saved to the database and it looks like this –
O:8:"WP_Query":49:{ ⋮ s:7:"request";s:590:"SELECT wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) WHERE 1=1 AND ( ⋮ AND ( ( wp_postmeta.meta_key = '_sku' AND wp_postmeta.meta_value IN ('testsku','test%%') ) ) AND wp_posts.post_type = 'product' AND ((wp_posts.post_status = 'publish')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_title ASC "; s:5:"posts";a:1:{i:0;O:7:"WP_Post":24:{s:2:"ID";i:207;s:11:"post_author";s:1:"1";s:9:"post_date";s:19:"2013-06-07 11:38:12";s:13:"post_date_gmt";s:19:"2013-06-07 11:38:12"; s:12:"post_content";s:27:"Pellentesque habitant morbi" ...}} ⋮ }
Have a closer look in line 7 to see how test%%% was transformed back. However, the mentioned length of $request is still 590. During deserialization, an additional number of characters will be treated as the value of $request, and this can rise to the content of $post_content feature of the post recovered. The latter is the content of a product recovered with the shortcode. It is a piece of cake for the hacker to adjust, and with apt alignment, a PHP object can be easily injected.
Related Post – WordPress Maintenance Checklist
As per this vulnerability flaw, the shop manager has the right to delete certain files on the server, further taking control over any administrator account.
In most cases, arbitrary file deletion is not considered risky as the hacker can only delete website’s index.php file leading to the Denial of Service.
Let us gain more knowledge of how deleting plugin files in WordPress can deactivate security checks and eventually lead to the full website takeover.
There is an unpatched design flaw in WordPress’s privilege system. The hacker is in control of an account with the user role shop manager. Shop Managers are employees of a store, and they have the authority of making changes to the products, orders, and customers.
The hacker easily gains this access through XSS vulnerabilities and phishing attacks. The moment the hacker exploits this vulnerability, the shop manager takes over the administrator account, followed by executing the code on the server.
WordPress takes care of privileges by allocating certain capabilities to varied roles. As and when the role of the shop manager is defined, edit_users capability is assigned. This is done so that the manager is able to make changes to the customer accounts of the store. This whole flaw process takes place when the plugin is being installed.
woocommerce/includes/class-wc-install.php
// Shop manager role. add_role( 'shop_manager', // Internal name of the new role 'Shop manager', // The label for displaying array( // Capabilities ⋮ 'read_private_posts' => true, 'edit_users' => true, 'edit_posts' => true, ⋮ ) );
This role then gets stored in the database as the main setting of WordPress. This means that the user role is free of the plugin and exist despite the plugin being inactive. As and when an authenticated user attempts to make changes to another user, a call to current_user_can() is made ensuring that only privileged users have the right to perform the action. This is explained with the help of an example below –
$target_user_id = $_GET['target_user_id']; if(current_user_can('edit_user', $target_user_id)) { edit_user($target_user_id); }
By default, the edit_users capability authorizes the users enjoying this privilege, for instance – shop managers, to make changes to any user and even administrator, and updating their passwords.
Keeping in mind the security aspect, the WooCommerce has to specify that the shop managers should be capable enough to make changes to the user, but only those with the customer role.
To do so, WooCommerce can include meta capabilities. These meta capabilities are applied as functions, and they are known as current_user_can(). Rather than just returning true as the default behavior, the meta privilege function’s return value will decide whether or not the current user is allowed to perform that action. Have a look at the abstracted version of WooCommerce’s meta privilege filter –
Function disallow_editing_of_admins( $capability, $target_user_id) { // If the user is an admin return false and disallows the action if($capability == "edit_user" && user_is_admin($target_user_id)) { return false; } else { return true; } } add_filter(‘map_meta_cap’, ‘disallow _editing_of_admins’);
To be clear, the reported unpatched vulnerability doesn’t reside in the WordPress core or WooCommerce plugin itself.Instead, the vulnerability exists in a plugin, called WooCommerce Checkout Manager, that extends the functionality of WooCommerce by allowing eCommerce sites to customize forms on their checkout pages and is currently being used by more than 60,000 websites.The vulnerability in question is an “arbitrary file upload” issue that can be exploited by unauthenticated, remote attackers if the vulnerable sites have “Categorize Uploaded Files” option enabled within WooCommerce Checkout Manager plugin settings.WooCommerce Checkout Manager version 4.2.6, which is the latest available plugin at the time of writing, is vulnerable to this issue.
Related Post – How To Remove Malware From WordPress Site
While the filters are in action, they are only enforced when the plugin is active. Now, the issue is that the user roles get stocked in the database and exist despite the plugin being disabled. This means that if due to any reason WooCommerce was disabled, the meta privilege check which inhibits shop managers from changing administrators will not execute and the default behavior of acknowledging the users with edit_users to change any user, even administrators, will take place. This will let the shop managers update the password for the admin account and then take hold of the whole website.
First and foremost, make sure you upgrade it to the latest version, i.e. 3.6.5. Remember, plugins don’t update by default. This means that the admins will have to do this on their own through the wp-admin dashboard/plugins sidebar.
With this release, shop managers only have the right to edit users with customer role (by default). There is also a whitelist of roles that the shop managers can edit.
Redesigning how the whole WordPress permission communicate with the plugins might be a time-consuming process.
Is your woocomerce hacked, have no idea how to clean it up. Leave it to our experts at WP hacked Help. Get in touch with us with your details.
Related Posts –