Vulnerability fixed in WordPress WooCommerce Multi Currency plugin.

The WooCommerce Multi Currency plugin (7,700+ sales on Envato) fixed a broken access control vulnerability in version 2.1.17 and below that could allow customers to change the price of all products.

Authenticated Product Price Change

CVSS v3.1: 6.5 (Medium)

The plugin has a “Import Fixed Price” feature, that can be used to set up custom prices in different currencies in every product, which will overwrite the prices calculated by exchange rates:

The import function, import_csv(), is loaded by the wmc_bulk_fixed_price AJAX hook in the “woocommerce-multi-currency/includes/import-export/import-csv.php” script, line 24:

private function __construct() {
   add_action( 'wp_ajax_wmc_bulk_fixed_price', array( $this, 'import_csv' ) );
}

public function import_csv() {

   $ext = explode( '.', $_FILES['csv_file']['name'] );
   $pos = sanitize_text_field( $_POST['pos'] );
   $row = sanitize_text_field( $_POST['row'] );

   if ( in_array( $_FILES['csv_file']['type'], array(
         'text/csv',
         'application/vnd.ms-excel'
      ) ) && end( $ext ) == 'csv' ) {
      if ( ( $file_data = fopen( $_FILES['csv_file']['tmp_name'], "r" ) ) !== false ) {
         $size   = ( $_FILES['csv_file']['size'] );
         $header = fgetcsv( $file_data );

         if ( $pos == 0 ) {
            $pos = ftell( $file_data );
         }

         fseek( $file_data, $pos );

         for ( $i = 0; $i < 30; $i ++ ) {
            $data = fgetcsv( $file_data );
            if ( ! empty( $data ) ) {

               $reg        = $sale = array();
               $id         = $data[0];
               $src        = array_combine( $header, $data );
               $currencies = $this->get_active_currencies();

               foreach ( $currencies as $currency ) {
                  $reg[ $currency ]  = isset( $src[ $currency ] ) ? $src[ $currency ] : '';
                  $sale[ $currency ] = isset( $src[ $currency . '-sale' ] ) ? $src[ $currency . '-sale' ] : '';
               }

               update_post_meta( $id, '_regular_price_wmcp', json_encode( $reg ) );
               update_post_meta( $id, '_sale_price_wmcp', json_encode( $sale ) );
               $row ++;
            }
         }

         $current_pos = ftell( $file_data );

         $percentage = round( $current_pos / $size * 100 );

         $data = array( 'pos' => $current_pos, 'percentage' => $percentage, 'row' => $row );

         wp_send_json_success( $data );
      } else {
         wp_send_json_error( array( 'message' => esc_html__( 'Unable to read file', 'woocommerce-multi-currency' ) ) );
      }
   } else {
      wp_send_json_error( array( 'message' => esc_html__( 'File not supported', 'woocommerce-multi-currency' ) ) );
   }
}

The function lacks a capability check and a security nonce, and therefore is accessible to all authenticated users, which includes WooCommerce customers.

A user could upload a CSV file to change the price of one or multiple products. Only the current currency, which can be found in the product page, and the product ID, which can be found in the source of the same page, are required to create the CSV file:

ID,Product,Type,SKU,"Variation Attributes",USD,USD-sale
10,,,,,0.01,0.01
15,,,,,0.01,0.01
...
...

The minimum value for the new price(s) cannot be lower than 0.01, regardless of the currency:

The vulnerability is particularly damaging for online shops selling digital goods because the attacker will have time to download the goods. It is important to verify every order because the hack doesn’t change the product’s price in the backend, hence the shop manager may unlikely notice it immediately:

Recommendations

Update immediately if you have version 2.1.17 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

Due to unsuccessful attempts to contact the developers on August 19, 2021, the issue was escalated to Envato on September 01, 2021, and a new version 2.1.18 was released on September 02, 2021.

Stay informed about the latest vulnerabilities