CVE-2024-31822 (published 2024-04-29T18:15Z)

An issue in Ecommerce-CodeIgniter-Bootstrap commit v. d22b54e8915f167a135046ceb857caaf8479c4da allows a remote attacker to execute arbitrary code via the saveLanguageFiles method of the Languages.php component.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/kirilkirkov/Ecommerce-CodeIgniter-Bootstrap
commit_details: repo_url: https://github.com/kirilkirkov/Ecommerce-CodeIgniter-Bootstrap
author: Kiril Kirkov
author_date: 2024-01-02 21:59:46+02:00
msg: Vulnerability fixes from Lion Tree
repository: repo_url: https://github.com/kirilkirkov/Ecommerce-CodeIgniter-Bootstrap
repo_name: kirilkirkov/Ecommerce-CodeIgniter-Bootstrap
description: Responsive, Multi-Vendor, MultiLanguage Online Store Platform (shopping cart solution)
repo_language: PHP
owner: kirilkirkov
file_changes: filename: Languages.php
change_type: ModificationType.MODIFY
diff: @@ -97,7 +97,7 @@ class Languages extends ADMIN_Controller
             }
             $php_value = str_replace("'", '&#39;', $_POST['php_values'][$i]);
 			$php_value = str_replace('"', '&#34;', $php_value);
-            $phpFileInclude .= '$lang[\'' . htmlentities($_POST['php_keys'][$i]) . '\'] = \'' . $php_value . '\';' . "\n";
+            $phpFileInclude .= '$lang[\'' . htmlentities(addslashes($_POST['php_keys'][$i])) . '\'] = \'' . $php_value . '\';' . "\n";
             $prevFile = $phpFile;
             $i++;
         }
@@ -113,7 +113,7 @@ class Languages extends ADMIN_Controller
                 savefile($prevFile, $jsFileInclude);
                 $jsFileInclude = "var lang = { \n";
             }
-            $jsFileInclude .= htmlentities($_POST['js_keys'][$i]) . ':' . '"' . htmlentities($_POST['js_values'][$i]) . '",' . "\n";
+            $jsFileInclude .= htmlentities(addslashes($_POST['js_keys'][$i])) . ':' . '"' . htmlentities(addslashes($_POST['js_values'][$i])) . '",' . "\n";
             $prevFile = $jsFile;
             $i++;
         }
@@ -123,12 +123,33 @@ class Languages extends ADMIN_Controller
 
     private function getLangFolderForEdit()
     {
+        if(!ctype_alnum($_GET['editLang'])) {
+            redirect('admin/languages');
+        }
+
+        $dir = 'application' . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR . '' . $_GET['editLang'] . DIRECTORY_SEPARATOR;
+        if(!is_dir(rtrim($dir, DIRECTORY_SEPARATOR))) {
+            redirect('admin/languages');
+        }
+
         $langFiles = array();
-        $files = rreadDir('application' . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR . '' . $_GET['editLang'] . DIRECTORY_SEPARATOR);
+        $files = rreadDir($dir);
         $arrPhpFiles = $arrJsFiles = array();
         foreach ($files as $ext => $filesLang) {
             foreach ($filesLang as $fileLang) {
                 if ($ext == 'php') {
+
+                    $file_content = file_get_contents($fileLang);
+                    $tokens = token_get_all($file_content);
+                    foreach ($tokens as $tokenK => $token) {
+                        if ($token[0] == T_VARIABLE) {
+                            if($token[1] != '$lang') {
+                                throw new \Exception('Invalid variable name in file ' . $fileLang . ' on line ' . $token[2] . '');
+                            }
+                        }
+                        unset($tokens[$tokenK]);
+                    }
+
                     require $fileLang;
                     if (isset($lang)) {
                         $arrPhpFiles[$fileLang] = $lang;

programming_language: PHP
filename: Publish.php
change_type: ModificationType.MODIFY
diff: @@ -151,13 +151,16 @@ class Publish extends ADMIN_Controller
     /*
      * called from ajax
      */
-
-    public function removeSecondaryImage()
-    {
+    public function removeSecondaryImage() {
         if ($this->input->is_ajax_request()) {
-            $img = '.' . DIRECTORY_SEPARATOR . 'attachments' . DIRECTORY_SEPARATOR . 'shop_images' . DIRECTORY_SEPARATOR . '' . $_POST['folder'] . DIRECTORY_SEPARATOR . $_POST['image'];
-            unlink($img);
+            $basePath = realpath('.' . DIRECTORY_SEPARATOR . 'attachments' . DIRECTORY_SEPARATOR . 'shop_images' . DIRECTORY_SEPARATOR);
+    
+            $folder = realpath($basePath . DIRECTORY_SEPARATOR . $_POST['folder']);
+            $image = $_POST['image'];
+    
+            if ($folder !== false && strpos($folder, $basePath) === 0 && is_file($folder . DIRECTORY_SEPARATOR . $image)) {
+                unlink($folder . DIRECTORY_SEPARATOR . $image);
+            }
         }
     }
-
 }

programming_language: PHP
filename: Orders_model.php
change_type: ModificationType.MODIFY
diff: @@ -78,14 +78,18 @@ class Orders_model extends CI_Model
         $arr = $result->row_array();
         $products = unserialize($arr['products']);
         foreach ($products as $product) {
+                if (!is_numeric($product['product_quantity']) || (int)$product['product_info']['id'] < 1) {
+                    continue;
+                }
+
                 if (isset($operator)) {
-                    if (!$this->db->query('UPDATE products SET quantity=quantity' . $operator . $product['product_quantity'] . ' WHERE id = ' . $product['product_info']['id'])) {
+                    if (!$this->db->query('UPDATE products SET quantity=quantity' . $operator . $product['product_quantity'] . ' WHERE id = ' . (int)$product['product_info']['id'])) {
                         log_message('error', print_r($this->db->error(), true));
                         show_error(lang('database_error'));
                     }
                 }
                 if (isset($operator_pro)) {
-                    if (!$this->db->query('UPDATE products SET procurement=procurement' . $operator_pro . $product['product_quantity'] . ' WHERE id = ' . $product['product_info']['id'])) {
+                    if (!$this->db->query('UPDATE products SET procurement=procurement' . $operator_pro . $product['product_quantity'] . ' WHERE id = ' . (int)$product['product_info']['id'])) {
                         log_message('error', print_r($this->db->error(), true));
                         show_error(lang('database_error'));
                     }

programming_language: PHP