File Upload Path Validation Error in unilogies/bumsys
Reported on
Apr 25th 2023
Description
An administrator user can use the easyUpload
function to create files in any path of the system where the application has write permissions.
This vulnerability arises because the application is using user input to build the file path and does not properly validate this input.
Proof of Concept
The vulnerable php code is in core/functions.php
, on method easyUpload
.
This functions receives 4 parameters:
-The file itself
-The path of the file
-The new name for the file --> In some cases, it is empty and is generated randomly
-The type of the file --> Used correctly for File Type validation
Without any validation, the file is created on the File System using this construction, as we can see in line 1569 and 1583:
UPLOAD_BASE_PATH + $location + $filename + $extension
The function easyUpload
is used in multiple places and in some of them, it receives parameters that are directly passed from request input.
We can see an example on module/products/ajax.php
, on line 524.
There, easyUpload
is receiving this parameters:
array $file,
string $location="products/{$_POST["productCode"]}",
string $newFileName=join("-", $pv) . "_" . $_POST["productVariationCode"][$vKey],
string $type="image"
As we can see, the location and the newFileName are constructed with $_POST
variables. We can then craft a malicious request with a Path Traversal on productVariationCode
parameter, as shown in the image:
../../../../../../../../../../../../../../var/www/html/bumsys/inventedPath
We have printed the real path that is being used to create the image:
/var/www/html/bumsys/assets/upload/products/1242142141241241245/Red_../../../../../../../../../../../../../../var/www/html/bumsys/inventedPath.jpg
As we can see, the image has been uploaded on the file system path:
Another example is on module/peoples/ajax.php
, on line 522.
Impact
A user with administrator privileges can upload files in any path of the system without any restriction.
SECURITY.md
exists
7 months ago
Hello, I have updated the issue. Could you please confirm it is fixed?
Hi Khurshid, the file storing on arbitrary paths is fixed, but the directory is creating anyway, because the mkdir is before the realpath validation.
You should change the order of the IFs that are on line 1571 and 1576, first must check if realpath of $uploadDir
contains realpath of DIR_UPLOAD
and then, if it is OK, run the mkdir.
With this, it will be full fixed.
Regards
Hi agains Khurshid, ignore the previous solution, because with that if the directory does not exist, realpath returns False.
But as I said before, the file creation is fixed but the directory creation does not and an attacker can create a folder in any path of the system where application has permissions.
Hello Miralles, Yes the realpath return false if the path not exist. So I had to do such way. I think this is system issue. What do you think? and what will be the best fix?
Hi Khursid, I think the best fix would be to control the input variables to avoid having special characters such as dots.
It could be done with a regex similar to this:
if (!preg_match('/^[a-zA-Z0-9\/_-]+$/', $location)) {
return "Invalid characters in location";
}
The problem is that there are points like this where you configure a dot on the $location
variable and this would fail. You should also review all the points where you call easyUpload
and remove all the special chars on the path builiding.
I think, it would best if I remove the path traversal characters. Like this:
$location= str_replace( array( "./", "../", ".", ".." ), "", $location );
Hi Khurshid, that's OK too.
With invalid input data, it would be replaced and the directory created with mkdir would be inside UPLOAD_DIR
:
You should review the construction of path on newEmployee image, because the dot that are you setting would be deleted, but I assume this would not be a problem.
With this appending on ajax_data.php before the mkdir
call, the vulnerability will be full fixed.
Regards
Hi Khursid, I have reviewed the fix commit and I see that finally you are using this replace function:
$location= str_replace( array( "./", "../"), "", $location );
With this, on Linux servers, path traversal is protected, but on Wndows, it could still be exploited. I don't know if your system requirements are to deploy only on Linux machines, but maybe you have to take it on account. If it could be deployed on Windows, maybe is better the original replace function you send yesterday:
$location= str_replace( array( "./", "../", ".", ".." ), "", $location );
Thanks for the recognition, regards!