Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fixed critical upload vulnerability (#552)
Co-authored-by: Nicholas Ferreira <nickguitar.dll@hotmail.com>
  • Loading branch information
Nickguitar and Nicholas Ferreira committed Nov 10, 2021
1 parent 8c82b8a commit b1af3bd
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions lib/FileUtility.php
Expand Up @@ -184,11 +184,17 @@ public static function makeSafeFilename($filename)

/* Is the file extension safe? */
$fileExtension = self::getFileExtension($filename);
if (in_array($fileExtension, $GLOBALS['badFileExtensions']))

/* Use a whitelist instead of a blacklist to prevent possible bypasses */
if (!preg_match("/(?i)\.(pdf|docx?|rtf|odt?g?|txt|wpd|jpe?g|png|csv|xlsx?|ppt|msg|heic|tiff?|html?|bmp|wps|xps)$/i", $fileExtension))
{
$filename .= ".txt";
}
/* if (in_array($fileExtension, $GLOBALS['badFileExtensions']))
{
$filename .= '.txt';
}

*/
return $filename;
}

Expand Down Expand Up @@ -563,7 +569,7 @@ public static function getUploadFileFromPost($siteID, $subDirectory, $id)
if (!eval(Hooks::get('FILE_UTILITY_SPACE_CHECK'))) return;

$uploadPath = FileUtility::getUploadPath($siteID, $subDirectory);
$newFileName = $_FILES[$id]['name'];
$newFileName = FileUtility::makeSafeFilename($_FILES[$id]['name']);

// Could just while(file_exists) it, but I'm paranoid of infinate loops
// Shouldn't have 1000 files of the same name anyway
Expand Down

2 comments on commit b1af3bd

@xalt7x
Copy link

@xalt7x xalt7x commented on b1af3bd Aug 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Nickguitar , @RussH
It doesn't work for me as expected.
With this change each uploaded files (even with extension from the whitelist) gets "txt" extension appended at the end of the filename
I'm currently applying such workaround for this commit

@@ -186,7 +186,11 @@
         $fileExtension = self::getFileExtension($filename);
         
         /* Use a whitelist instead of a blacklist to prevent possible bypasses */
+/*
         if (!preg_match("/(?i)\.(pdf|docx?|rtf|odt?g?|txt|wpd|jpe?g|png|csv|xlsx?|ppt|msg|heic|tiff?|html?|bmp|wps|xps)$/i", $fileExtension))
+*/
+        $GoodFileExtensions = array('bmp', 'csv', 'doc', 'docx', 'heic', 'html', 'jpeg', 'jpg', 'mhtml', 'msg', 'odg', 'odt', 'pages', 'pdf', 'png', 'ppt', 'pptx', 'rtf', 'tiff', 'wpd', 'wps', 'xls', 'xlsx', 'xps');
+        if (!in_array($fileExtension, $GoodFileExtensions))
         {
             $filename .= ".txt";
         }

@RussH
Copy link
Member

@RussH RussH commented on b1af3bd Sep 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Alt37 thank you - verified your findings and am applying your revision. Sorry - had verified the original fix caught 'bad' extensions, but hadn't checked it actually permitted 'good' extensions to pass!

Please sign in to comment.