CVE-2021-44674: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') (CWE-22)
value: An information exposure issue has been discovered in Opmantek Open-AudIT 4.2.0. The vulnerability allows an authenticated attacker to read file outside of the restricted directory.
CWE description: The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
CVSS v3 base score: 6.5
Published: 2022-01-03T13:15Z
Repository: https://github.com/Opmantek/open-audit
Language: PHP
Files changed: code_igniter/application/controllers/devices.php, code_igniter/application/models/m_devices.php
Commit date: 2021-11-26 22:50:04 +1000
Commit message: Fix for image upload path traversal issue.

Diff: diff --git a/code_igniter/application/controllers/devices.php b/code_igniter/application/controllers/devices.php
index fbe05f999..7e261a741 100644
--- a/code_igniter/application/controllers/devices.php
+++ b/code_igniter/application/controllers/devices.php
@@ -683,21 +683,14 @@ class Devices extends MY_Controller
         if (empty($this->response->meta->sub_resource_id)) {
             $this->response->meta->sub_resource_id = 0;
         }
         $attachment = $this->m_devices->read_sub_resource($this->response->meta->id, $this->response->meta->sub_resource, $this->response->meta->sub_resource_id, '*', '', '', '');
         $this->load->helper('file');
-        if (php_uname('s') === 'Windows NT') {
-            $temp = explode('\\', $attachment[0]->attributes->filename);
-        } else {
-            $temp = explode('/', $attachment[0]->attributes->filename);
-        }
-        $filename = $temp[count($temp)-1];
-        $filename = preg_replace('/'.$this->response->meta->id.'_/', '', $filename, 1);
         header('Content-Type: '.get_mime_by_extension($attachment[0]->attributes->filename));
-        header('Content-Disposition: attachment;filename="'.$filename.'"');
+        header('Content-Disposition: attachment;filename="'.basename($attachment[0]->attributes->filename).'"');
         header('Cache-Control: max-age=0');
-        readfile($attachment[0]->attributes->filename);
+        readfile($_SERVER['DOCUMENT_ROOT'] . '/open-audit/custom_images/' . basename($attachment[0]->attributes->filename));
     }
 
     /**
      * [delete description]
      * @return [type] [description]
diff --git a/code_igniter/application/models/m_devices.php b/code_igniter/application/models/m_devices.php
index c735efa15..7983c4c42 100644
--- a/code_igniter/application/models/m_devices.php
+++ b/code_igniter/application/models/m_devices.php
@@ -729,11 +729,11 @@ class M_devices extends MY_Model
                 }
             } else if ( ! empty($CI->response->meta->received_data->attributes->filename)) {
                 $sql = 'INSERT INTO `image` VALUES (NULL, ?, ?, ?, ?, ?, NOW())';
                 $data = array(intval($CI->response->meta->id),
                         $CI->response->meta->received_data->attributes->name,
-                        $CI->response->meta->received_data->attributes->filename,
+                        basename($CI->response->meta->received_data->attributes->filename),
                         $CI->response->meta->received_data->attributes->orientation,
                         $CI->user->full_name);
                 $this->db->query($sql, $data);
                 return true;
             } else {

Vulnerable code:         if (php_uname('s') === 'Windows NT') {
            $temp = explode('\\', $attachment[0]->attributes->filename);
        } else {
            $temp = explode('/', $attachment[0]->attributes->filename);
        }
        $filename = $temp[count($temp)-1];
        $filename = preg_replace('/'.$this->response->meta->id.'_/', '', $filename, 1);
        header('Content-Disposition: attachment;filename="'.$filename.'"');
        readfile($attachment[0]->attributes->filename);
                        $CI->response->meta->received_data->attributes->filename,
Fixed code:         header('Content-Disposition: attachment;filename="'.basename($attachment[0]->attributes->filename).'"');
        readfile($_SERVER['DOCUMENT_ROOT'] . '/open-audit/custom_images/' . basename($attachment[0]->attributes->filename));
                        basename($CI->response->meta->received_data->attributes->filename),