Vulnerability: An unrestricted file upload issue in HorizontCMS through 1.0.0-beta allows an authenticated remote attacker (with access to the FileManager) to upload and execute arbitrary PHP code by uploading a PHP payload, and then using the FileManager's rename function to provide the payload (which will receive a random name on the server) with the PHP extension, and finally executing the PHP file via an HTTP GET request to /storage/<php_file_name>. NOTE: the vendor has patched this while leaving the version number at 1.0.0-beta.
Vulnerability ID: CVE-2020-27387
CWE: CWE-434
Severity score: 6.4
Project: https://github.com/ttimot24/HorizontCMS
Published: 2020-11-05
File: app/Controllers/FileManagerController.php
Commit message: Security bug fix.
Commit author: Timot Tarjani

Vulnerable version (before fix):
 class FileManagerController extends Controller{         /**      * Display a listing of the resource. public function fileupload(){             if ($this->request->hasFile('up_file')){                  foreach($this->request->up_file as $file){                    $images[] = $file->store(str_replace("storage/", "", $this->request->input('dir_path')));                 }                  if($this->request->ajax()){ public function rename(){          if($this->request->isMethod('POST')){              if(\Storage::move($this->request->input('old_file'), $this->request->input('new_file'))){                 if($this->request->ajax()){                     return response()->json(['success' => trans('File successfully renamed!')]);                 }

Fixed version (after fix):
 class FileManagerController extends Controller{        private function validationRegex(){         return '/^.*\.('.implode('|',["php","php5","php7"]).')$/i';     }       /**      * Display a listing of the resource. public function fileupload(){             if ($this->request->hasFile('up_file')){                  foreach($this->request->up_file as $file){                                          if(!preg_match($this->validationRegex(), strtolower($file))){                         $images[] = $file->store(str_replace("storage/", "", $this->request->input('dir_path')));                     }                 }                  if($this->request->ajax()){ public function rename(){          if($this->request->isMethod('POST')){              $new_file = $this->request->input('new_file');              if(!preg_match($this->validationRegex(), strtolower($new_file)) && \Storage::move($this->request->input('old_file'), $new_file)){                 if($this->request->ajax()){                     return response()->json(['success' => trans('File successfully renamed!')]);                 }

Patch:
patch: @@ -10,6 +10,10 @@
 class FileManagerController extends Controller{
  
 
+    private function validationRegex(){
+        return '/^.*\.('.implode('|',["php","php5","php7"]).')$/i';
+    }
+
 
     /**
      * Display a listing of the resource.
@@ -60,7 +64,10 @@ public function fileupload(){
             if ($this->request->hasFile('up_file')){
 
                 foreach($this->request->up_file as $file){
-                   $images[] = $file->store(str_replace("storage/", "", $this->request->input('dir_path')));
+                    
+                    if(!preg_match($this->validationRegex(), strtolower($file))){
+                        $images[] = $file->store(str_replace("storage/", "", $this->request->input('dir_path')));
+                    }
                 }
 
                 if($this->request->ajax()){
@@ -223,7 +230,9 @@ public function rename(){
 
         if($this->request->isMethod('POST')){
 
-            if(\Storage::move($this->request->input('old_file'), $this->request->input('new_file'))){
+            $new_file = $this->request->input('new_file');
+
+            if(!preg_match($this->validationRegex(), strtolower($new_file)) && \Storage::move($this->request->input('old_file'), $new_file)){
                 if($this->request->ajax()){
                     return response()->json(['success' => trans('File successfully renamed!')]);
                 }
path: app/Controllers/FileManagerController.php