The WooCommerce Dynamic Pricing and Discounts plugin, which has 19,700+ sales on Envato Market, fixed multiple unauthenticated vulnerabilities affecting version 2.4.1 and below.
Unauthenticated Settings Import and Stored XSS.
CVSS v3.1: 7.1 (High)
In the __construct
method of the “wc-dynamic-pricing-and-discounts/classes/rp-wcdpd-settings.class.php” script, the plugin loads the import
function if the $_FILES['rp_wcdpd_settings']['rp_wcdpd_import']
file is being uploaded:
// Settings import call if (!empty($_FILES['rp_wcdpd_settings']['name']['rp_wcdpd_import'])) { add_action('wp_loaded', array($this, 'import')); }
The import
function is located L2476:
public function import() { try { // Check if file was uploaded correctly if ($_FILES['rp_wcdpd_settings']['error']['rp_wcdpd_import'] !== UPLOAD_ERR_OK || !is_uploaded_file($_FILES['rp_wcdpd_settings']['tmp_name']['rp_wcdpd_import'])) { throw new Exception; } // Get file contents $contents = file_get_contents($_FILES['rp_wcdpd_settings']['tmp_name']['rp_wcdpd_import']); // Contents empty if (empty($contents)) { throw new Exception; } // Decode data $data = json_decode($contents, true); // Check if required properties are set if (!isset($data['settings']) || empty($data['timestamp']) || empty($data['checksum'])) { throw new Exception; } // Check data integrity if ($data['checksum'] !== RightPress_Help::get_hash(false, $data['settings'])) { throw new Exception; } // Update settings entry in the database update_option('rp_wcdpd_settings', $data['settings']); ... ...
It lacks a capability check and a security nonce and thus is accessible to everyone, authenticated or not.
An unauthenticated user can import the plugin’s settings. Because some fields aren’t sanitised, the attacker can inject JavaScript code into the imported JSON-encoded file. The code will be executed on every product pages of the WooCommerce e-shop, in the frontend:
It’s also possible to replace the JS code with any HTML tags such as a Meta Refresh tag to redirect visitors and customers to a malicious website for instance.
Unauthenticated Settings Export
CVSS v3.1: 5.3 (Medium)
Line 77, the plugin registers the export
function via the wp_loaded
action if $_REQUEST['rp_wcdpd_export_settings']
is not empty:
// Settings export call if (!empty($_REQUEST['rp_wcdpd_export_settings'])) { add_action('wp_loaded', array($this, 'export')); }
The export
is found line 2448:
public function export() { // Get settings $settings = get_option('rp_wcdpd_settings', array()); // Format export data $data = array( 'settings' => $settings, 'timestamp' => time(), 'checksum' => RightPress_Help::get_hash(false, $settings), ); // Send headers header('Content-type: application/json'); header('Content-Disposition: attachment; filename="rp_wcdpd_settings.json"'); // Output content and exit echo json_encode($data); exit; }
This function lacks a capability check and is accessible to everyone, authenticated or not.
An unauthenticated user can export the plugin’s settings, inject JavaSript code into the JSON file and reimport it using the previous vulnerability.
Recommendations
Update immediately if you have version 2.4.1 or below installed. If you are using our web application firewall for WordPress, NinjaFirewall WP Edition (free) and NinjaFirewall WP+ Edition (premium), you are protected against this vulnerability.
Timeline
The vulnerability was reported to Envato on Augut 18, 2021, and a new version 2.4.2 was released on August 22, 2021 (despite our recommendations, the new version still lacks a securiy nonce to prevent against CSRF attacks in the import
function).
Stay informed about the latest vulnerabilities
- Running WordPress? You can get email notifications about vulnerabilities in the plugins or themes installed on your blog.
- On Twitter: @nintechnet