Vulnerability: Path traversal in pimcore/pimcore This affects the package pimcore/pimcore before 6.8.8. A Local FIle Inclusion vulnerability exists in the downloadCsvAction function of the CustomReportController class (bundles/AdminBundle/Controller/Reports/CustomReportController.php). An authenticated user can reach this function with a GET request at the following endpoint: /admin/reports/custom-report/download-csv?exportFile=&91;filename]. Since exportFile variable is not sanitized, an attacker can exploit a local file inclusion vulnerability.
Vulnerability ID: GHSA-h7f9-cvh5-qw7f
CWE: CWE-22
Severity score: 0
Project: https://github.com/pimcore/pimcore
Published: 2021-02-25
File: bundles/AdminBundle/Controller/Reports/CustomReportController.php
Commit message: Fixed LFI in custom report csv download
Commit author: Bernhard Rusch

Vulnerable version (before fix):
 public function createCsvAction(Request $request)         $progress = $progress > 1 ? 1 : $progress;          return new JsonResponse([             'exportFile' => $exportFile,             'offset' => $offset,             'progress' => $progress,             'finished' => empty($result['data']) || count($result['data']) < $limit, public function downloadCsvAction(Request $request)     {         $this->checkPermission('reports');         if ($exportFile = $request->get('exportFile')) {             $response = new BinaryFileResponse($exportFile);             $response->headers->set('Content-Type', 'text/csv; charset=UTF-8');             $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'export.csv');

Fixed version (after fix):
 public function createCsvAction(Request $request)         $progress = $progress > 1 ? 1 : $progress;          return new JsonResponse([             'exportFile' => basename($exportFile),             'offset' => $offset,             'progress' => $progress,             'finished' => empty($result['data']) || count($result['data']) < $limit, public function downloadCsvAction(Request $request)     {         $this->checkPermission('reports');         if ($exportFile = $request->get('exportFile')) {             $exportFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . '/' . basename($exportFile);             $response = new BinaryFileResponse($exportFile);             $response->headers->set('Content-Type', 'text/csv; charset=UTF-8');             $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'export.csv');

Patch:
patch: @@ -433,7 +433,7 @@ public function createCsvAction(Request $request)
         $progress = $progress > 1 ? 1 : $progress;
 
         return new JsonResponse([
-            'exportFile' => $exportFile,
+            'exportFile' => basename($exportFile),
             'offset' => $offset,
             'progress' => $progress,
             'finished' => empty($result['data']) || count($result['data']) < $limit,
@@ -451,6 +451,7 @@ public function downloadCsvAction(Request $request)
     {
         $this->checkPermission('reports');
         if ($exportFile = $request->get('exportFile')) {
+            $exportFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . '/' . basename($exportFile);
             $response = new BinaryFileResponse($exportFile);
             $response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
             $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'export.csv');
path: bundles/AdminBundle/Controller/Reports/CustomReportController.php