From d4d74c549fb140e6a9eda8776784924e751d1b4b Mon Sep 17 00:00:00 2001 From: Kaue Reinbold Date: Sun, 25 Jan 2026 17:47:47 -0300 Subject: [PATCH] fix(api): prevent cleartext password storage in logs --- .../Extensions/DatabaseExtensions.cs | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/server/api/dotnet/Reminders.Api/Extensions/DatabaseExtensions.cs b/src/server/api/dotnet/Reminders.Api/Extensions/DatabaseExtensions.cs index 5f63620..6b81ce6 100644 --- a/src/server/api/dotnet/Reminders.Api/Extensions/DatabaseExtensions.cs +++ b/src/server/api/dotnet/Reminders.Api/Extensions/DatabaseExtensions.cs @@ -17,17 +17,9 @@ public static WebApplication EnsureDatabaseAvailable(this WebApplication app) var maxRetryAttempts = app.Configuration.GetValue("DatabaseRetry:MaxAttempts") ?? 5; var baseSeconds = app.Configuration.GetValue("DatabaseRetry:BaseSeconds") ?? 2; + // Redact connection string for logging (never store password in cleartext variables) var configuredConn = app.Configuration.GetConnectionString("DefaultConnection") ?? "(none)"; - string connPreview; - try - { - // redact password for logs - connPreview = configuredConn.Replace("Password=", "Password=***"); - } - catch - { - connPreview = "(invalid)"; - } + var connPreview = RedactPassword(configuredConn); var policy = Policy.Handle() .WaitAndRetry(maxRetryAttempts, retryAttempt => @@ -66,4 +58,24 @@ public static WebApplication EnsureDatabaseAvailable(this WebApplication app) return app; } + + private static string RedactPassword(string connectionString) + { + if (string.IsNullOrWhiteSpace(connectionString)) + return "(none)"; + + try + { + // Use regex to redact password value + return System.Text.RegularExpressions.Regex.Replace( + connectionString, + @"(Password|Pwd)\s*=\s*[^;]*", + "$1=***", + System.Text.RegularExpressions.RegexOptions.IgnoreCase); + } + catch + { + return "(invalid)"; + } + } }