From faa58440452960206efc72dc427a83428cab8b31 Mon Sep 17 00:00:00 2001 From: mleem97 <52848568+mleem97@users.noreply.github.com> Date: Fri, 14 Aug 2026 00:00:09 +0000 Subject: [PATCH 1/2] Fix path traversal in SetPortrait method in CustomEmployeeManager --- src/API/CustomEmployeeManager.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/API/CustomEmployeeManager.cs b/src/API/CustomEmployeeManager.cs index 9b4512b6..1229951b 100644 --- a/src/API/CustomEmployeeManager.cs +++ b/src/API/CustomEmployeeManager.cs @@ -891,10 +891,19 @@ private static void SetPortrait(Transform card, string employeeId) string assetsDir = Path.Combine(MelonEnvironment.UserDataDirectory, "ModAssets"); string? imagePath = null; - foreach (var ext in new[] { ".jpg", ".png" }) + + // [Security] Prevent path traversal attack in portrait image path construction + if (employeeId.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0 || employeeId.Contains("..")) + { + CrashLog.Log($"[Security] CustomEmployee: Invalid characters in portrait employeeId={employeeId}"); + } + else { - string candidate = Path.Combine(assetsDir, employeeId + ext); - if (File.Exists(candidate)) { imagePath = candidate; break; } + foreach (var ext in new[] { ".jpg", ".png" }) + { + string candidate = Path.Combine(assetsDir, employeeId + ext); + if (File.Exists(candidate)) { imagePath = candidate; break; } + } } if (imagePath != null) From dbf339166aab7c7ec9884d252ac21db1c2af2f72 Mon Sep 17 00:00:00 2001 From: mleem97 <52848568+mleem97@users.noreply.github.com> Date: Fri, 14 Aug 2026 00:01:30 +0000 Subject: [PATCH 2/2] Fix path traversal in SetPortrait method in CustomEmployeeManager