We detected and reported a file deletion vulnerability in WooCommerce, which was fixed in version
3.4.6. Arbitrary file deletion
vulnerabilities aren’t considered critical in most cases as the only thing an attacker can cause is a Denial of Service by deleting the index.php of the website.
This post details how deleting certain plugin files in WordPress can disable security checks and then leads to a full site takeover. At fault is an unpatched design flaw in the privilege
system of WordPress.
Affected were over 4 million WooCommerce shops. No other requirements other
than an attacker being in control of an account with the user role shop manager were required. Shop managers
are employees of the store that can manage orders, products and customers. Such access could be obtained via XSS vulnerabilities
or phishing attacks. Once the vulnerability described here is exploited, the shop manager can take over any administrator account and
then execute code on the server.
The vulnerability was automatically detected by our security analysis solution RIPS in 200 KLOC WooCommerce code within 2 minutes.
The way WordPress handles privileges is by assigning certain capabilities to different roles. When the shop manager role is
defined, it is assigned the
edit_users capability so that they are allowed to edit customer accounts of the store. This happens
during the installation process of the plugin.
The role is then stored in the database as a core setting of WordPress. This means that the user role is now independent of
the plugin and will exist even if the plugin is inactive.
Whenever an authenticated user tries to edit another user, a call to
current_user_can() is made to ensure
only privileged users can perform that action.
Example of a call to current_user_can()
The logic of the call is “Can the user trying to perform this action edit the specific user with the ID
By default the
edit_users capability allows users who have this privilege, e.g. shop managers, to edit any user, even administrators and perform actions such as updating their passwords.
For security reasons, WooCommerce needs to specify that shop managers should be able to edit users, but only those with the customer role.
To do so, plugins such as WooCommerce can add meta capabilities. Meta capabilities are implemented as functions
that are called by
current_user_can(). Instead of simply returning true as the default behavior, the return value
of the meta privilege function will decide whether or not the current user can perform that action. An abstracted version of WooCommerce’s meta
privilege filter is shown below.
Example of a meta capability
As an example, when
current_user_can(‘edit_user’, 1) is called, the filter will be executed to determine if the user with the
ID 1 (
$target_user_id) is an admin and if so disallow editing and return false. Otherwise it will let the user proceed. The actual, more complex
meta cap hook of WooCommerce is stored in
woocommerce/includes/wc-user-functions.php on line
The Design Flaw
While these filters work, they only get executed when the plugin is active. The issue is that user roles get stored in the database
and exist even if the plugin is disabled. This means that if WooCommerce was disabled for some reason, the meta privilege check which
restricts shop managers from editing administrators would not execute and the default behavior of allowing users with
edit_users to edit
any user, even administrators, would occur. This would allow shop managers to update the password of the admin account and then take over the entire site.
Disabling the plugin as a shop manager
By default, only administrators can disable plugins. However, RIPS detected an arbitrary file deletion vulnerability in WooCommerce. This
vulnerability allows shop managers to delete any file on the server that is writable. By deleting the main file of WooCommerce,
WordPress will be unable to load the plugin and then disables it.
The file deletion vulnerability occurred in the logging feature of WooCommerce. Logs are stored as .log files in the
When a shop manager wants to delete a log file, he submits it’s filename as a GET parameter. As the following code snippets show this is handled insecurely.
The issue is that the filename (
$handle) is appended to the Log directory (
wp-content/wc-logs/) and then passed to
$handle../../plugins/woocommerce-3.4.5/woocommerce.php the file
be deleted, causing WooCommerce to get disabled.
The file deletion vulnerability was automatically detected by our leading SAST solution RIPS. The scan report can be found here:
|2018/08/30||The Arbitrary File Deletion Vulnerabiliy was reported to the Automattic security team on Hackerone.|
|2018/09/11||The vulnerability was triaged and verified by the security team.|
|2018/10/11||A patch was released.|
In a previous post we demonstrated how to exploit a file delete vulnerability in WordPress and how to elevate the file delete into a remote code execution vulnerability. The downside of that method was that all data was lost on the target site. The method detailed in this blogpost shows how a file deletion vulnerability in any WordPress plugin can be used to escalate privileges where meta privileges are used. This design flaw still persists. File deletion vulnerabilities are not uncommon and even occur in the WordPress core itself. Note, that file delete vulnerabilities can also be exploited with Phar deserialization under certain circumstances.