On August 20, 2020, the Wordfence Threat Intelligence team was made aware of several vulnerabilities that had been patched in Discount Rules for WooCommerce, a WordPress plugin installed on over 40,000 sites. We released a firewall rule to protect against these vulnerabilities the same day. During our investigation, we also discovered a separate set of vulnerabilities in the plugin that were not yet patched, and released a firewall rule to protect against these separate vulnerabilities the next day, on August 21, 2020.
We reached out to the plugin’s team at Flycart on August 21, 2020, and received a response almost immediately. After we provided the full vulnerability disclosure, Flycart let us know that they were aware of one of the issues we disclosed, and released an interim patch on August 22, 2020. Flycart followed this up with a more comprehensive patch on September 2, 2020 and a patch that addressed the last of the issues on September 9, 2020.
Affected Plugin: Discount Rules for WooCommerce
Plugin Slug: woo-discount-rules
Affected Versions: < 2.2.1
CVE ID: Pending
CVSS Score: 7.4(High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:L
Fully Patched Version: 2.2.1
Discount Rules for WooCommerce is a WordPress plugin designed to work with the WooCommerce e-Commerce plugin to create custom rules for discounts, such as “2 for 1” specials.
The vulnerabilities that were originally patched in the plugin were AJAX actions present in the “v2” codebase of the plugin that allowed any site visitor to add, modify, and delete these rules and view any existing coupons. Unfortunately, the plugin maintained a separate “v1” codebase containing an earlier version of this functionality. Anyone visiting the site could switch between the v1 and v2 codebase by visiting any page on the site and adding a awdr_switch_plugin_to
query string parameter set to v1
or v2
.
if (isset($_GET['awdr_switch_plugin_to']) && in_array($_GET['awdr_switch_plugin_to'], array('v1', 'v2'))) { $awdr_switched_to_version = $version = sanitize_text_field($_GET['awdr_switch_plugin_to']); update_option('advanced_woo_discount_rules_load_version', $version); }
The initial patch released on August 22, 2020, added a capability check to prevent this switching, but any sites using the “v1” code were still vulnerable.
Once the plugin was set to use the “v1” codebase, a number of AJAX actions became available providing similar functionality to the patched actions in “v2”:
add_action('wp_ajax_savePriceRule', array($this->discountBase, 'savePriceRule')); add_action('wp_ajax_saveCartRule', array($this->discountBase, 'saveCartRule')); add_action('wp_ajax_saveConfig', array($this->discountBase, 'saveConfig')); add_action('wp_ajax_resetWDRCache', array($this->discountBase, 'resetWDRCache')); add_action('wp_ajax_loadProductSelectBox', array($this->discountBase, 'loadProductSelectBox')); add_action('wp_ajax_loadCoupons', array($this->discountBase, 'loadCoupons'));</pre> <code></code> add_action('wp_ajax_UpdateStatus', array($this->discountBase, 'updateStatus')); add_action('wp_ajax_RemoveRule', array($this->discountBase, 'removeRule')); add_action('wp_ajax_doBulkAction', array($this->discountBase, 'doBulkAction')); add_action('wp_ajax_createDuplicateRule', array($this->discountBase, 'createDuplicateRule'));
Like the previous patched functions, the “v1” AJAX functions did not perform capability checks or nonce checks. Unlike the AJAX actions that were patched in the “v2” codebase, these actions did require a user to be logged in. Due to the nature of e-Commerce, most online stores allow potential customers to register before making a purchase, so this would not have been a major obstacle to attackers.
In addition to allowing attackers to view all available coupons on a site and activate, duplicate, and delete discount rules, at least two of the actions, savePriceRule
and saveCartRule
were also vulnerable to stored Cross-Site Scripting(XSS) in several of the rule fields.
For example, an attacker could send a POST
request to wp-admin/admin-ajax.php
with the action
set to savePriceRule
or saveCartRule
and inject malicious JavaScript into one of the fields of a discount rule by adding it to the data
parameter. The next time an administrator viewed or edited discount rules, the malicious JavaScript would be executed in their browser. Doing so could lead to site takeover by adding a backdoor to plugin or theme files, adding a malicious administrator, or any number of other actions.
Source Credit – WordFence