WooCommerce Dynamic Pricing and Discounts plugin fixed multiple vulnerabilities.

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