From 0f7853f961ba2f68f8dcd358acaad6c6eb7980e6 Mon Sep 17 00:00:00 2001 From: Miguel Ribeiro Date: Sat, 2 Mar 2024 15:58:22 +0100 Subject: [PATCH] fix: file upload bypass vulnerability (#181) --- endpoints/payments/add.php | 15 +++++++++++++++ endpoints/subscription/add.php | 15 +++++++++++++++ includes/version.php | 2 +- index.php | 2 +- nginx.conf | 5 +++++ settings.php | 6 ++---- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/endpoints/payments/add.php b/endpoints/payments/add.php index b14483f8e..440451cef 100644 --- a/endpoints/payments/add.php +++ b/endpoints/payments/add.php @@ -9,9 +9,15 @@ function sanitizeFilename($filename) { $filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename); $filename = str_replace(" ", "-", $filename); + $filename = str_replace(".", "", $filename); return $filename; } + function validateFileExtension($fileExtension) { + $allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'jtif', 'webp']; + return in_array($fileExtension, $allowedExtensions); + } + function getLogoFromUrl($url, $uploadDir, $name) { $ch = curl_init($url); @@ -72,6 +78,7 @@ function resizeAndUploadLogo($uploadedFile, $uploadDir, $name) { $timestamp = time(); $originalFileName = $uploadedFile['name']; $fileExtension = pathinfo($originalFileName, PATHINFO_EXTENSION); + $fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png'; $fileName = $timestamp . '-payments-' . sanitizeFilename($name) . '.' . $fileExtension; $uploadFile = $uploadDir . $fileName; @@ -87,6 +94,10 @@ function resizeAndUploadLogo($uploadedFile, $uploadDir, $name) { $image = imagecreatefrompng($uploadFile); } elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') { $image = imagecreatefromjpeg($uploadFile); + } elseif ($fileExtension === 'gif') { + $image = imagecreatefromgif($uploadFile); + } elseif ($fileExtension === 'webp') { + $image = imagecreatefromwebp($uploadFile); } else { // Handle other image formats as needed return ""; @@ -120,6 +131,10 @@ function resizeAndUploadLogo($uploadedFile, $uploadDir, $name) { imagepng($resizedImage, $uploadFile); } elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') { imagejpeg($resizedImage, $uploadFile); + } elseif ($fileExtension === 'gif') { + imagegif($resizedImage, $uploadFile); + } elseif ($fileExtension === 'webp') { + imagewebp($resizedImage, $uploadFile); } else { return ""; } diff --git a/endpoints/subscription/add.php b/endpoints/subscription/add.php index 4a2690a53..94d0fbb07 100644 --- a/endpoints/subscription/add.php +++ b/endpoints/subscription/add.php @@ -9,9 +9,15 @@ function sanitizeFilename($filename) { $filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename); $filename = str_replace(" ", "-", $filename); + $filename = str_replace(".", "", $filename); return $filename; } + function validateFileExtension($fileExtension) { + $allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp']; + return in_array($fileExtension, $allowedExtensions); + } + function getLogoFromUrl($url, $uploadDir, $name) { $ch = curl_init($url); @@ -72,6 +78,7 @@ function resizeAndUploadLogo($uploadedFile, $uploadDir, $name) { $timestamp = time(); $originalFileName = $uploadedFile['name']; $fileExtension = pathinfo($originalFileName, PATHINFO_EXTENSION); + $fileExtension = validateFileExtension($fileExtension) ? $fileExtension : 'png'; $fileName = $timestamp . '-' . sanitizeFilename($name) . '.' . $fileExtension; $uploadFile = $uploadDir . $fileName; @@ -87,6 +94,10 @@ function resizeAndUploadLogo($uploadedFile, $uploadDir, $name) { $image = imagecreatefrompng($uploadFile); } elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') { $image = imagecreatefromjpeg($uploadFile); + } elseif ($fileExtension === 'gif') { + $image = imagecreatefromgif($uploadFile); + } elseif ($fileExtension === 'webp') { + $image = imagecreatefromwebp($uploadFile); } else { // Handle other image formats as needed return ""; @@ -120,6 +131,10 @@ function resizeAndUploadLogo($uploadedFile, $uploadDir, $name) { imagepng($resizedImage, $uploadFile); } elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') { imagejpeg($resizedImage, $uploadFile); + } elseif ($fileExtension === 'gif') { + imagegif($resizedImage, $uploadFile); + } elseif ($fileExtension === 'webp') { + imagewebp($resizedImage, $uploadFile); } else { return ""; } diff --git a/includes/version.php b/includes/version.php index 0385f0593..d5d77521d 100644 --- a/includes/version.php +++ b/includes/version.php @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/index.php b/index.php index 3f6a587fc..f5d1420b1 100644 --- a/index.php +++ b/index.php @@ -135,7 +135,7 @@ - +
diff --git a/nginx.conf b/nginx.conf index 312ac5571..284ea77e1 100644 --- a/nginx.conf +++ b/nginx.conf @@ -42,6 +42,11 @@ http { deny all; return 403; } + + location ~* images/uploads/logos/.*\.php$ { + deny all; + return 403; + } } include /etc/nginx/conf.d/*.conf; diff --git a/settings.php b/settings.php index 390741f0d..20f7a704c 100644 --- a/settings.php +++ b/settings.php @@ -506,9 +506,7 @@ 31 && !$inUse) { ?> -
- x -
+
x
@@ -534,7 +532,7 @@ <?= translate('logo_preview', $i18n) ?>