From 00ba80cc5c1762b9e0a706e34bd5f1525de8e85b Mon Sep 17 00:00:00 2001
From: Prasad <prasad@vtiger.com>
Date: Mon, 22 Apr 2024 19:46:58 +0530
Subject: [PATCH] Added checkFileAccessIn within sub-directory and refactored
 email attachment fix.

---
 modules/Emails/views/MassSaveAjax.php | 10 +++-------
 vtlib/Vtiger/Utils.php                | 12 +++++++++++-
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/modules/Emails/views/MassSaveAjax.php b/modules/Emails/views/MassSaveAjax.php
index be14047ea..f230e536c 100644
--- a/modules/Emails/views/MassSaveAjax.php
+++ b/modules/Emails/views/MassSaveAjax.php
@@ -220,13 +220,9 @@ class Emails_MassSaveAjax_View extends Vtiger_Footer_View {
 					$encryptFileName = Vtiger_Util_Helper::getEncryptedFileName($binFile);
 					$newFilePath = $upload_file_path . $current_id . "_" . $encryptFileName;
 
-					Vtiger_Utils::checkFileAccess($oldFilePath);
-
-					//restrict attachment only from storage directory
-					$oldFileRelPath = str_replace('\\', '/', str_replace(realpath($root_directory).DIRECTORY_SEPARATOR, "", realpath($oldFilePath)));
-					if (strpos($oldFileRelPath, "storage/") !== 0) {
-                                                throw new Exception("Attachment access denied");
-                                        }
+					//expect attachment only from storage directory
+					Vtiger_Utils::checkFileAccessIn($oldFilePath, ["storage"]);
+					
 					copy($oldFilePath, $newFilePath);
 
 					$sql1 = "insert into vtiger_crmentity (crmid,smcreatorid,smownerid,setype,description,createdtime,modifiedtime) values(?, ?, ?, ?, ?, ?, ?)";
diff --git a/vtlib/Vtiger/Utils.php b/vtlib/Vtiger/Utils.php
index e5415688d..772ab948b 100644
--- a/vtlib/Vtiger/Utils.php
+++ b/vtlib/Vtiger/Utils.php
@@ -88,11 +88,21 @@ class Vtiger_Utils {
 	}
 
 	/** 
-	 * Function to check the file access is made within web root directory. 
+	 * Function to check the file access is made within web root directory.
 	 * @param String File path to check
 	 * @param Boolean False to avoid die() if check fails
 	 */
 	static function checkFileAccess($filepath, $dieOnFail=true) {
+		return checkFileAccessIn($filepath, null, $dieOnFail);
+	}
+
+	/** 
+	 * Function to check the file access is made within web root directory (with optional sub-directories)
+	 * @param String File path to check
+	 * @param Array Relative paths within web root directory.
+	 * @param Boolean False to avoid die() if check fails
+	 */
+	static function checkFileAccessIn($filepath, array $relpaths = null, $dieOnFail=true) {
 		global $root_directory;
 
 		// Set the base directory to compare with
-- 
GitLab