CVE-2020-21809: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: SQL Injection vulnerability in NukeViet CMS module Shops 4.0.29 and 4.3 via the (1) listid parameter in detail.php and the (2) group_price or groupid parameters in search_result.php.
CWE description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
CVSS v3 base score: 9.8
Published: 2021-07-30T14:15Z
Repository: https://github.com/nukeviet/module-shops
Language: PHP
Files changed: modules/shops/funcs/detail.php, modules/shops/funcs/search_result.php
Commit date: 2019-12-23 09:01:16 +0700
Commit message: Security fixes

Diff: diff --git a/modules/shops/funcs/detail.php b/modules/shops/funcs/detail.php
index b629b7a..4d921d4 100644
--- a/modules/shops/funcs/detail.php
+++ b/modules/shops/funcs/detail.php
@@ -14,13 +14,13 @@ if (!defined('NV_IS_MOD_SHOPS')) {
 
 if ($nv_Request->isset_request('check_quantity', 'post')) {
     $id_pro = $nv_Request->get_int('id_pro', 'post', 0);
     $unit = $nv_Request->get_string('pro_unit', 'post', '');
     $listid = $nv_Request->get_string('listid', 'post');
-    $listid = explode(',', $listid);
+    $listid = array_map('intval', explode(',', $listid));
     asort($listid);
-    
+
     $quantity = $db->query('SELECT quantity FROM ' . $db_config['prefix'] . '_' . $module_data . '_group_quantity WHERE pro_id = ' . $id_pro . ' AND listgroup="' . implode(',', $listid) . '"')->fetchColumn();
     if (empty($quantity)) {
         $sum = 0;
         $count = 0;
         $listgroupid = GetGroupID($id_pro, 1);
@@ -30,11 +30,11 @@ if ($nv_Request->isset_request('check_quantity', 'post')) {
                 if ($parent_info['in_order']) {
                     $count++;
                 }
             }
         }
-        
+
         $result = $db->query('SELECT listgroup, quantity FROM ' . $db_config['prefix'] . '_' . $module_data . '_group_quantity WHERE pro_id = ' . $id_pro);
         while (list ($listgroup, $quantity) = $result->fetch(3)) {
             $listgroup = explode(',', $listgroup);
             $_t = 0;
             foreach ($listgroup as $_idgroup) {
@@ -44,11 +44,11 @@ if ($nv_Request->isset_request('check_quantity', 'post')) {
             }
             if ($_t == sizeof($listid) or empty($listid)) {
                 $sum += $quantity;
             }
         }
-        
+
         if ($sum == 0 or $count == sizeof($listid)) {
             die('NO_0_' . $lang_module['product_empty']);
         } else {
             die('NO_0_' . $lang_module['detail_pro_number'] . ': ' . $sum . ' ' . $unit);
         }
@@ -88,18 +88,18 @@ if ($global_array_shops_cat[$data_content['listcatid']]['form'] != '') {
             if (in_array($idtemplate, $listtemplate)) {
                 $listfield[] = $row['fid'];
                 $array_tmp[$row['field']] = unserialize($row['language']);
             }
         }
-        
+
         if (!empty($listfield)) {
             $result = $db->query('SELECT t1.field_value, t2.field FROM ' . $db_config['prefix'] . "_" . $module_data . "_field_value_" . NV_LANG_DATA . ' t1 INNER JOIN ' . $db_config['prefix'] . '_' . $module_data . '_field t2 WHERE t1.field_id=t2.fid AND t1.rows_id=' . $id);
             $data_content['template'] = $global_array_shops_cat[$data_content['listcatid']]['form'];
             while ($row = $result->fetch()) {
                 $data_content['array_custom'][$row['field']] = $row['field_value'];
             }
-            
+
             if (!empty($array_tmp)) {
                 foreach ($array_tmp as $f_key => $field) {
                     foreach ($field as $key_lang => $lang_data) {
                         if ($key_lang == NV_LANG_DATA) {
                             $data_content['array_custom_lang'][$f_key] = $lang_data[0];
@@ -115,35 +115,35 @@ if ($global_array_shops_cat[$data_content['listcatid']]['form'] != '') {
 $page_title = !empty($data_content[NV_LANG_DATA . '_tag_title']) ? $data_content[NV_LANG_DATA . '_tag_title'] : $data_content[NV_LANG_DATA . '_title'];
 $description = !empty($data_content[NV_LANG_DATA . '_tag_description']) ? $data_content[NV_LANG_DATA . '_tag_description'] : $data_content[NV_LANG_DATA . '_hometext'];
 
 if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
     $popup = $nv_Request->get_int('popup', 'post,get', 0);
-    
+
     $time_set = $nv_Request->get_int($module_data . '_' . $op . '_' . $id, 'session');
     if (empty($time_set)) {
         $nv_Request->set_Session($module_data . '_' . $op . '_' . $id, NV_CURRENTTIME);
         $sql = 'UPDATE ' . $db_config['prefix'] . '_' . $module_data . '_rows SET hitstotal=hitstotal+1 WHERE id=' . $id;
         $db->query($sql);
     }
-    
+
     $catid = $data_content['listcatid'];
     $base_url_rewrite = nv_url_rewrite(NV_BASE_SITEURL . 'index.php?' . NV_LANG_VARIABLE . '=' . NV_LANG_DATA . '&amp;' . NV_NAME_VARIABLE . '=' . $module_name . '&amp;' . NV_OP_VARIABLE . '=' . $global_array_shops_cat[$catid]['alias'] . '/' . $data_content[NV_LANG_DATA . '_alias'] . $global_config['rewrite_exturl'], true);
-    
+
     if ($_SERVER['REQUEST_URI'] != $base_url_rewrite and !$popup) {
         Header('Location: ' . $base_url_rewrite);
         die();
     }
-    
+
     // Lay don vi san pham
     $sql = $db->query('SELECT * FROM ' . $db_config['prefix'] . '_' . $module_data . '_units WHERE id = ' . $data_content['product_unit']);
     $data_unit = $sql->fetch();
     $data_unit['title'] = $data_unit[NV_LANG_DATA . '_title'];
-    
+
     // Hien thi tabs
     $sql = 'SELECT * FROM ' . $db_config['prefix'] . '_' . $module_data . '_tabs where active=1 ORDER BY weight ASC';
     $data_content['tabs'] = $nv_Cache->db($sql, 'id', $module_name);
-    
+
     $data_content['files'] = array();
     if (!empty($data_content['tabs'])) {
         // Download tai lieu san pham
         if ($pro_config['download_active']) {
             $result = $db->query('SELECT id, ' . NV_LANG_DATA . '_title title, ' . NV_LANG_DATA . '_description description, path, filesize, extension, download_groups FROM ' . $db_config['prefix'] . '_' . $module_data . '_files WHERE id IN (SELECT id_files FROM ' . $db_config['prefix'] . '_' . $module_data . '_files_rows WHERE id_rows=' . $data_content['id'] . ')');
@@ -151,11 +151,11 @@ if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
                 $row['filesize'] = !empty($row['filesize']) ? nv_convertfromBytes($row['filesize']) : $lang_module['download_file_unknown'];
                 $data_content['files'][] = $row;
             }
         }
     }
-    
+
     // Danh gia - Phan hoi
     $rating_total = 0;
     $result = $db->query('SELECT rating FROM ' . $db_config['prefix'] . '_' . $module_data . '_review WHERE product_id = ' . $data_content['id'] . ' AND status=1');
     $rating_count = $result->rowCount();
     if ($rating_count > 0) {
@@ -164,11 +164,11 @@ if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
         }
     }
     $data_content['rating_total'] = $rating_count;
     $data_content['rating_point'] = $rating_total;
     $data_content['rating_value'] = $rating_count > 0 ? round($rating_total / $rating_count) : 0;
-    
+
     // Xac dinh anh lon
     $homeimgfile = $data_content['homeimgfile'];
     if ($data_content['homeimgthumb'] == 1) {
         // image thumb
         $data_content['homeimgthumb'] = NV_BASE_SITEURL . NV_FILES_DIR . '/' . $module_upload . '/' . $homeimgfile;
@@ -181,33 +181,33 @@ if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
         $data_content['homeimgthumb'] = $data_content['homeimgfile'] = $homeimgfile;
     } else {
         // no image
         $data_content['homeimgthumb'] = NV_BASE_SITEURL . 'themes/' . $module_info['template'] . '/images/' . $module_file . '/no-image.jpg';
     }
-    
+
     // Tu khoa
     $array_keyword = array();
     $key_words = array();
     $_query = $db->query('SELECT a1.keyword keyword, a2.alias alias FROM ' . $db_config['prefix'] . '_' . $module_data . '_tags_id_' . NV_LANG_DATA . ' a1 INNER JOIN ' . $db_config['prefix'] . '_' . $module_data . '_tags_' . NV_LANG_DATA . ' a2 ON a1.tid=a2.tid WHERE a1.id=' . $data_content['id']);
     while ($row = $_query->fetch()) {
         $array_keyword[] = $row;
         $key_words[] = $row['keyword'];
     }
     $key_words = !empty($key_words) ? implode(',', $key_words) : '';
-    
+
     // metatag image facebook
     $meta_property['og:image'] = NV_MY_DOMAIN . $data_content['homeimgfile'];
-    
+
     // Fetch Limit
     $db->sqlreset()
         ->select(' id, listcatid, ' . NV_LANG_DATA . '_title, ' . NV_LANG_DATA . '_alias, homeimgfile, homeimgthumb, addtime, publtime, product_code, product_number, product_price, price_config, money_unit, discount_id, showprice, ' . NV_LANG_DATA . '_hometext,' . NV_LANG_DATA . '_gift_content, gift_from, gift_to')
         ->from($db_config['prefix'] . '_' . $module_data . '_rows')
         ->where('id!=' . $id . ' AND listcatid = ' . $data_content['listcatid'] . ' AND status=1')
         ->order('ID DESC')
         ->limit($pro_config['per_row'] * 2);
     $result = $db->query($db->sql());
-    
+
     $data_others = array();
     while (list ($_id, $listcatid, $title, $alias, $homeimgfile, $homeimgthumb, $addtime, $publtime, $product_code, $product_number, $product_price, $price_config, $money_unit, $discount_id, $showprice, $hometext, $gift_content, $gift_from, $gift_to) = $result->fetch(3)) {
         if ($homeimgthumb == 1) {
             // image thumb
             $thumb = NV_BASE_SITEURL . NV_FILES_DIR . '/' . $module_upload . '/' . $homeimgfile;
@@ -219,11 +219,11 @@ if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
             $thumb = $homeimgfile;
         } else {
             // no image
             $thumb = NV_BASE_SITEURL . 'themes/' . $module_info['template'] . '/images/' . $module_file . '/no-image.jpg';
         }
-        
+
         $data_others[] = array(
             'id' => $_id,
             'listcatid' => $listcatid,
             'title' => $title,
             'alias' => $alias,
@@ -244,11 +244,11 @@ if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
             'gift_to' => $gift_to,
             'link_pro' => NV_BASE_SITEURL . 'index.php?' . NV_LANG_VARIABLE . '=' . NV_LANG_DATA . '&amp;' . NV_NAME_VARIABLE . '=' . $module_name . '&amp;' . NV_OP_VARIABLE . '=' . $global_array_shops_cat[$data_content['listcatid']]['alias'] . '/' . $alias . $global_config['rewrite_exturl'],
             'link_order' => NV_BASE_SITEURL . 'index.php?' . NV_LANG_VARIABLE . '=' . NV_LANG_DATA . '&amp;' . NV_NAME_VARIABLE . '=' . $module_name . '&amp;' . NV_OP_VARIABLE . '=setcart&amp;id=' . $_id
         );
     }
-    
+
     $array_other_view = array();
     if (!empty($_SESSION[$module_data . '_proview'])) {
         $arrid = array();
         foreach ($_SESSION[$module_data . '_proview'] as $id_i => $data_i) {
             if ($id_i != $id) {
@@ -277,11 +277,11 @@ if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
                     $thumb = $homeimgfile;
                 } else {
                     // no image
                     $thumb = NV_BASE_SITEURL . 'themes/' . $module_info['template'] . '/images/' . $module_file . '/no-image.jpg';
                 }
-                
+
                 $array_other_view[] = array(
                     'id' => $_id,
                     'listcatid' => $listcatid,
                     'title' => $title,
                     'alias' => $alias,
@@ -303,13 +303,13 @@ if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
                     'link_order' => NV_BASE_SITEURL . 'index.php?' . NV_LANG_VARIABLE . '=' . NV_LANG_DATA . '&amp;' . NV_NAME_VARIABLE . '=' . $module_name . '&amp;' . NV_OP_VARIABLE . '=setcart&amp;id=' . $_id
                 );
             }
         }
     }
-    
+
     SetSessionProView($data_content['id'], $data_content[NV_LANG_DATA . '_title'], $data_content[NV_LANG_DATA . '_alias'], $data_content['addtime'], NV_BASE_SITEURL . 'index.php?' . NV_LANG_VARIABLE . '=' . NV_LANG_DATA . '&' . NV_NAME_VARIABLE . '=' . $module_name . '&' . NV_OP_VARIABLE . '=' . $global_array_shops_cat[$catid]['alias'] . '/' . $data_content[NV_LANG_DATA . '_alias'] . '-' . $data_content['id'], $data_content['homeimgthumb']);
-    
+
     // comment
     if (isset($site_mods['comment']) and isset($module_config[$module_name]['activecomm'])) {
         define('NV_COMM_ID', $data_content['id']); // ID bài viết hoặc
         define('NV_COMM_AREA', $module_info['funcs'][$op]['func_id']); // để đáp ứng comment ở bất cứ đâu không cứ là bài viết
         // check allow comemnt
@@ -319,16 +319,16 @@ if (nv_user_in_groups($global_array_shops_cat[$catid]['groups_view'])) {
         }
         define('NV_PER_PAGE_COMMENT', 5); // Số bản ghi hiển thị bình luận
         require_once NV_ROOTDIR . '/modules/comment/comment.php';
         $area = (defined('NV_COMM_AREA')) ? NV_COMM_AREA : 0;
         $checkss = md5($module_name . '-' . $area . '-' . NV_COMM_ID . '-' . $allowed . '-' . NV_CACHE_PREFIX);
-        
+
         $content_comment = nv_comment_module($module_name, $checkss, $area, NV_COMM_ID, $allowed, 1);
     } else {
         $content_comment = '';
     }
-    
+
     $contents = detail_product($data_content, $data_unit, $data_others, $array_other_view, $content_comment, $compare_id, $popup, $idtemplate, $array_keyword);
 } else {
     $nv_redirect = NV_BASE_SITEURL . 'index.php?' . NV_LANG_VARIABLE . '=' . NV_LANG_DATA . '&amp;' . NV_NAME_VARIABLE . '=' . $module_name;
     redict_link($lang_module['detail_no_permission'], $lang_module['redirect_to_back_shops'], $nv_redirect);
 }
@@ -337,6 +337,6 @@ if ($popup) {
     echo $contents;
 } else {
     include NV_ROOTDIR . '/includes/header.php';
     echo nv_site_theme($contents);
     include NV_ROOTDIR . '/includes/footer.php';
-}
\ No newline at end of file
+}
diff --git a/modules/shops/funcs/search_result.php b/modules/shops/funcs/search_result.php
index 4070b87..227ca3a 100644
--- a/modules/shops/funcs/search_result.php
+++ b/modules/shops/funcs/search_result.php
@@ -36,11 +36,11 @@ if (! empty($group_price)) {
     $group_price = nv_base64_decode($group_price);
     $group_price = unserialize($group_price);
     if (!empty($group_price)) {
         $search .= " AND";
         foreach ($group_price as $i => $group_price_i) {
-            $group_price_i = explode('-', $group_price_i);
+            $group_price_i = array_map('intval', explode('-', $group_price_i));
             if ($group_price_i[0] <= $group_price_i[1]) {
                 $search .= ($i > 0 ? " OR " : "") . " product_price BETWEEN " . $group_price_i[0] . " AND " . $group_price_i[1] . " ";
             } else {
                 $search .= ($i > 0 ? " OR " : "") . " product_price > " . $group_price_i[0] . " ";
             }

Vulnerable code:     $listid = explode(',', $listid);
    
        
        
        
            
    
    
    
    
    
    
    
    
    
    
    
    
        
    
                
    
    
        
    
}
            $group_price_i = explode('-', $group_price_i);
Fixed code:     $listid = array_map('intval', explode(',', $listid));
























}
            $group_price_i = array_map('intval', explode('-', $group_price_i));