CVE-2020-5237 (published 2020-02-05T14:15Z)

Multiple relative path traversal vulnerabilities in the oneup/uploader-bundle before 1.9.3 and 2.1.5 allow remote attackers to upload, copy, and modify files on the filesystem (potentially leading to arbitrary code execution) via the (1) filename parameter to BlueimpController.php; the (2) dzchunkindex, (3) dzuuid, or (4) filename parameter to DropzoneController.php; the (5) qqpartindex, (6) qqfilename, or (7) qquuid parameter to FineUploaderController.php; the (8) x-file-id or (9) x-file-name parameter to MooUploadController.php; or the (10) name or (11) chunk parameter to PluploadController.php. This is fixed in versions 1.9.3 and 2.1.5.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-22
cwe_name: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
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.
extended_description: 
            Many file operations are intended to take place within a restricted directory. By using special elements such as ".." and "/" separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the "../" sequence, which in most modern operating systems is interpreted as the parent directory of the current location. This is referred to as relative path traversal. Path traversal also covers the use of absolute pathnames such as "/usr/local/bin" to access unexpected files. This is referred to as absolute path traversal.
         
         

Fix information:
repo_url: https://github.com/1up-lab/OneupUploaderBundle
commit_details: repo_url: https://github.com/1up-lab/OneupUploaderBundle
author: David Greminger
author_date: 2020-02-04 11:37:36+01:00
msg: Merge pull request from GHSA-x8wj-6m73-gfqp
repository: repo_url: https://github.com/1up-lab/OneupUploaderBundle
repo_name: 1up-lab/OneupUploaderBundle
description: This Symfony bundle provides a server implementation for handling single and multiple file uploads using either FineUploader, jQuery File Uploader, YUI3 Uploader, Uploadify, FancyUpload, MooUpload, Plupload or Dropzone. Features include chunked uploads, orphanages, Gaufrette and Flysystem support.
repo_language: PHP
owner: 1up-lab
file_changes: filename: DropzoneController.php
change_type: ModificationType.MODIFY
diff: @@ -42,8 +42,8 @@ class DropzoneController extends AbstractChunkedController
     protected function parseChunkedRequest(Request $request)
     {
         $totalChunkCount = $request->get('dztotalchunkcount');
-        $index = $request->get('dzchunkindex');
-        $last = ((int) $index + 1) === (int) $totalChunkCount;
+        $index = (int) $request->get('dzchunkindex');
+        $last = ($index + 1) === (int) $totalChunkCount;
         $uuid = $request->get('dzuuid');
 
         /**

programming_language: PHP
filename: FineUploaderController.php
change_type: ModificationType.MODIFY
diff: @@ -40,11 +40,11 @@ class FineUploaderController extends AbstractChunkedController
 
     protected function parseChunkedRequest(Request $request)
     {
-        $index = $request->get('qqpartindex');
-        $total = $request->get('qqtotalparts');
+        $index = (int) $request->get('qqpartindex');
+        $total = (int) $request->get('qqtotalparts');
         $uuid = $request->get('qquuid');
         $orig = $request->get('qqfilename');
-        $last = ((int) $total - 1) === (int) $index;
+        $last = ($total - 1) === $index;
 
         return [$last, $uuid, $index, $orig];
     }

programming_language: PHP
filename: PluploadController.php
change_type: ModificationType.MODIFY
diff: @@ -35,7 +35,7 @@ class PluploadController extends AbstractChunkedController
         $session = $this->container->get('session');
 
         $orig = $request->get('name');
-        $index = $request->get('chunk');
+        $index = (int) $request->get('chunk');
         $last = (int) $request->get('chunks') - 1 === (int) $request->get('chunk');
 
         // it is possible, that two clients send a file with the

programming_language: PHP
filename: FilesystemStorage.php
change_type: ModificationType.MODIFY
diff: @@ -38,6 +38,9 @@ class FilesystemStorage implements ChunkStorageInterface
 
     public function addChunk($uuid, $index, UploadedFile $chunk, $original)
     {
+        // Prevent path traversal attacks
+        $uuid = basename($uuid);
+
         $filesystem = new Filesystem();
         $path = sprintf('%s/%s', $this->directory, $uuid);
         $name = sprintf('%s_%s', $index, $original);
@@ -106,6 +109,9 @@ class FilesystemStorage implements ChunkStorageInterface
 
     public function getChunks($uuid)
     {
+        // Prevent path traversal attacks
+        $uuid = basename($uuid);
+
         $finder = new Finder();
         $finder
             ->in(sprintf('%s/%s', $this->directory, $uuid))->files()->sort(function (\SplFileInfo $a, \SplFileInfo $b) {

programming_language: PHP
filename: FlysystemStorage.php
change_type: ModificationType.MODIFY
diff: @@ -65,6 +65,9 @@ class FlysystemStorage implements ChunkStorageInterface
 
     public function addChunk($uuid, $index, UploadedFile $chunk, $original)
     {
+        // Prevent path traversal attacks
+        $uuid = basename($uuid);
+
         $this->unhandledChunk = [
             'uuid' => $uuid,
             'index' => $index,
@@ -136,6 +139,9 @@ class FlysystemStorage implements ChunkStorageInterface
 
     public function getChunks($uuid)
     {
+        // Prevent path traversal attacks
+        $uuid = basename($uuid);
+
         return $this->filesystem->listFiles($this->prefix.'/'.$uuid);
     }
 

programming_language: PHP
filename: GaufretteStorage.php
change_type: ModificationType.MODIFY
diff: @@ -98,6 +98,9 @@ class GaufretteStorage extends StreamManager implements ChunkStorageInterface
      */
     public function addChunk($uuid, $index, UploadedFile $chunk, $original)
     {
+        // Prevent path traversal attacks
+        $uuid = basename($uuid);
+
         $this->unhandledChunk = [
             'uuid' => $uuid,
             'index' => $index,
@@ -170,6 +173,9 @@ class GaufretteStorage extends StreamManager implements ChunkStorageInterface
 
     public function getChunks($uuid)
     {
+        // Prevent path traversal attacks
+        $uuid = basename($uuid);
+
         $results = $this->filesystem->listKeys($this->prefix.'/'.$uuid);
 
         /* exclude files without an index, so if there is a completed file which

programming_language: PHP