CVE-2023-6566 (published 2023-12-07T00:15Z)

Business Logic Errors in GitHub repository microweber/microweber prior to 2.0.

CVSS v3 base score: 6.5, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N)

Weakness information:
cwe_id: NVD-CWE-Other
cwe_name: Other
description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/microweber/microweber
commit_details: repo_url: https://github.com/microweber/microweber
author: Peter Ivanov
author_date: 2023-06-07 16:47:46+03:00
msg: update
repository: repo_url: https://github.com/microweber/microweber
repo_name: microweber/microweber
description: Drag and Drop Website Builder and CMS with E-commerce
repo_language: HTML
owner: microweber
file_changes: filename: CartManager.php
change_type: ModificationType.MODIFY
diff: @@ -243,7 +243,7 @@ class CartManager extends Crud
             $params = $params2;
         }
 
-        $table =  'cart';
+        $table = 'cart';
         $params['table'] = $table;
         $skip_sid = false;
         if (!defined('MW_API_CALL')) {
@@ -292,10 +292,36 @@ class CartManager extends Crud
         if (is_array($get)) {
             foreach ($get as $k => $item) {
                 if (is_array($item)) {
+
+
                     if (isset($item['rel_id']) and isset($item['rel_type']) and $item['rel_type'] == 'content') {
                         $item['content_data'] = $this->app->content_manager->data($item['rel_id']);
                         $item['url'] = $this->app->content_manager->link($item['rel_id']);
                         $item['picture'] = $this->app->media_manager->get_picture($item['rel_id']);
+
+                        if (isset($params['for_checkout']) and $params['for_checkout']) {
+                            // check if content is unpublished or deleted
+                            $checkContent = get_content_by_id($item['rel_id']);
+                            $removeFromCart = false;
+                            if ($checkContent == false) {
+                                $removeFromCart = true;
+                            }
+
+                            if ($checkContent and isset($checkContent['is_deleted']) and $checkContent['is_deleted'] == 1) {
+                                $removeFromCart = true;
+                            }
+                            if ($checkContent and isset($checkContent['is_active']) and $checkContent['is_active'] == 0) {
+                                $removeFromCart = true;
+                            }
+
+                            if ($removeFromCart) {
+                                $this->remove_item($item['id']);
+                                unset($get[$k]);
+                                continue;
+                            }
+                        }
+
+
                     }
                     if (isset($item['custom_fields_data']) and $item['custom_fields_data'] != '') {
                         $item = $this->app->format->render_item_custom_fields_data($item);
@@ -330,7 +356,7 @@ class CartManager extends Crud
             return;
         }
         $params = array();
-        $table =  'cart';
+        $table = 'cart';
         $params['table'] = $table;
         $params['order_id'] = $order_id;
         $get = $this->app->database_manager->get($params);
@@ -455,7 +481,7 @@ class CartManager extends Crud
             $cart_return = $check_cart;
 
 
-            $table =  'cart';
+            $table = 'cart';
             $cart_data_to_save = array();
             $cart_data_to_save['qty'] = $cart['qty'];
             $cart_data_to_save['id'] = $cart['id'];
@@ -477,7 +503,7 @@ class CartManager extends Crud
     public function empty_cart()
     {
         $sid = mw()->user_manager->session_id();
-        $cart_table =  'cart';
+        $cart_table = 'cart';
 
         Cart::where('order_completed', 0)->where('session_id', $sid)->delete();
         $this->no_cache = true;
@@ -659,10 +685,10 @@ class CartManager extends Crud
                 $found = false;
                 foreach ($content_custom_fields as $cf) {
                     if (isset($cf['type']) and isset($cf['name']) and $cf['type'] != 'price') {
-                        if(isset($data[$cf['name_key']])){
+                        if (isset($data[$cf['name_key']])) {
                             $cf['name'] = $data[$cf['name_key']];
                         }
-                   } elseif (isset($cf['type']) and $cf['type'] == 'price' and isset($cf['name']) and isset($cf['value'])) {
+                    } elseif (isset($cf['type']) and $cf['type'] == 'price' and isset($cf['name']) and isset($cf['value'])) {
                         if ($cf['value'] != '') {
                             if (isset($product_prices[$cf['name']])) {
                                 $prices[$cf['name']] = $product_prices[$cf['name']];
@@ -737,7 +763,7 @@ class CartManager extends Crud
             ksort($add);
             asort($add);
             $add = mw()->format->clean_xss($add);
-            $table =  'cart';
+            $table = 'cart';
 
 
             $cart = array();
@@ -873,7 +899,7 @@ class CartManager extends Crud
 
             if ($cur_sid != false) {
                 $c_id = $sid;
-                $table =  'cart';
+                $table = 'cart';
                 $params = array();
                 //   $params['order_completed'] = 0;
                 $params['session_id'] = $c_id;
@@ -942,7 +968,7 @@ class CartManager extends Crud
 
     public function table_name()
     {
-        return  'cart';
+        return 'cart';
     }
 
 

programming_language: PHP
filename: CheckoutManager.php
change_type: ModificationType.MODIFY
diff: @@ -57,6 +57,7 @@ class CheckoutManager
         $table_orders = 'cart_orders';
         $cart['session_id'] = $sid;
         $cart['order_completed'] = 0;
+        $cart['for_checkout'] = true;
         $cart['limit'] = 1;
         $mw_process_payment = true;
         $mw_process_payment_success = false;

programming_language: PHP
filename: CheckoutTest.php
change_type: ModificationType.MODIFY
diff: @@ -242,4 +242,114 @@ class CheckoutTest extends TestCase
     }
 
 
+
+
+
+    public function testCheckoutDeletedProduct()
+    {
+        mw()->database_manager->extended_save_set_permission(true);
+
+        $productPrice = rand(1, 9999);
+        $title = 'test testCheckoutDeletedProduct prod ' . $productPrice;
+        $params = array(
+            'title' => $title,
+            'content_type' => 'product',
+            'subtype' => 'product',
+            'custom_fields_advanced' => array(
+                array('type' => 'dropdown', 'name' => 'Color', 'value' => array('Purple', 'Blue')),
+                array('type' => 'price', 'name' => 'Price', 'value' => '9.99'),
+
+            ),
+            'data_fields_qty' => 10,
+            'is_deleted' => 1,
+            'is_active' => 1,);
+
+
+        $saved_id = save_content($params);
+        $get = get_content_by_id($saved_id);
+
+
+        $add_to_cart = array(
+            'content_id' => $saved_id,
+            'price' => $productPrice,
+        );
+        $cart_add = update_cart($add_to_cart);
+
+
+        $checkoutDetails = array();
+        $checkoutDetails['email'] = 'client@microweber.com';
+        $checkoutDetails['is_paid'] = 1;
+        $checkoutDetails['order_completed'] = 1;
+
+
+        $checkoutStatus = app()->order_manager->place_order($checkoutDetails);
+        $content_data_after_order = content_data($saved_id);
+        $this->assertEquals(10, $content_data_after_order['qty']);
+
+        $productQuery = \MicroweberPackages\Product\Models\Product::query();
+        $productQuery = $productQuery->whereHas('orders');
+        $products = $productQuery->get();
+        $this->assertTrue($products->isEmpty());
+
+        $order = get_order_by_id($checkoutStatus);
+        $this->assertNotNull($order);
+        $this->assertNull($order['amount']);
+
+    }
+
+
+
+
+    public function testCheckoutUnpublishedProduct()
+    {
+        mw()->database_manager->extended_save_set_permission(true);
+
+        $productPrice = rand(1, 9999);
+        $title = 'test testCheckoutUnpublishedProduct prod ' . $productPrice;
+        $params = array(
+            'title' => $title,
+            'content_type' => 'product',
+            'subtype' => 'product',
+            'custom_fields_advanced' => array(
+                array('type' => 'dropdown', 'name' => 'Color', 'value' => array('Purple', 'Blue')),
+                array('type' => 'price', 'name' => 'Price', 'value' => '9.99'),
+
+            ),
+            'data_fields_qty' => 11,
+            'is_deleted' => 0,
+            'is_active' => 0
+        );
+
+
+        $saved_id = save_content($params);
+        $get = get_content_by_id($saved_id);
+
+
+        $add_to_cart = array(
+            'content_id' => $saved_id,
+            'price' => $productPrice,
+        );
+        $cart_add = update_cart($add_to_cart);
+
+
+        $checkoutDetails = array();
+        $checkoutDetails['email'] = 'client@microweber.com';
+        $checkoutDetails['is_paid'] = 1;
+        $checkoutDetails['order_completed'] = 1;
+
+
+        $checkoutStatus = app()->order_manager->place_order($checkoutDetails);
+        $content_data_after_order = content_data($saved_id);
+        $this->assertEquals(11, $content_data_after_order['qty']);
+
+        $productQuery = \MicroweberPackages\Product\Models\Product::query();
+        $productQuery = $productQuery->whereHas('orders');
+        $products = $productQuery->get();
+        $this->assertTrue($products->isEmpty());
+
+        $order = get_order_by_id($checkoutStatus);
+        $this->assertNotNull($order);
+        $this->assertNull($order['amount']);
+
+    }
 }

programming_language: PHP