From 49212ba91d631433fec85750a564eca149cba5b5 Mon Sep 17 00:00:00 2001 From: Kaue Reinbold Date: Sun, 25 Jan 2026 18:06:31 -0300 Subject: [PATCH 1/2] fix(api): remove connection string from logs entirely Remove all connection string references from logs to eliminate any potential exposure of sensitive information. Logs now only show generic retry messages without database connection details. Changes: - Removed GetRedactedConnectionString() helper method - Removed RedactPassword() helper method - Updated log messages to exclude connection string preview - Logs now show: 'Database connectivity attempt {RetryCount} failed' Resolves CodeQL cleartext storage alerts by not logging connection string at all, even in redacted form. --- .../Extensions/DatabaseExtensions.cs | 33 ++----------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/src/server/api/dotnet/Reminders.Api/Extensions/DatabaseExtensions.cs b/src/server/api/dotnet/Reminders.Api/Extensions/DatabaseExtensions.cs index c0ffdd7..3ec0ad0 100644 --- a/src/server/api/dotnet/Reminders.Api/Extensions/DatabaseExtensions.cs +++ b/src/server/api/dotnet/Reminders.Api/Extensions/DatabaseExtensions.cs @@ -17,9 +17,6 @@ public static WebApplication EnsureDatabaseAvailable(this WebApplication app) var maxRetryAttempts = app.Configuration.GetValue("DatabaseRetry:MaxAttempts") ?? 5; var baseSeconds = app.Configuration.GetValue("DatabaseRetry:BaseSeconds") ?? 2; - // Get redacted connection string for logging (password never stored) - var connPreview = GetRedactedConnectionString(app.Configuration); - var policy = Policy.Handle() .WaitAndRetry(maxRetryAttempts, retryAttempt => { @@ -27,7 +24,7 @@ public static WebApplication EnsureDatabaseAvailable(this WebApplication app) return TimeSpan.FromSeconds(Math.Pow(baseSeconds, retryAttempt)) + jitter; }, (exception, timeSpan, retryCount, context) => { - logger?.LogWarning(exception, "Database connectivity attempt {RetryCount} failed for {ConnectionPreview}. Next retry in {Delay}.", retryCount, connPreview, timeSpan); + logger?.LogWarning(exception, "Database connectivity attempt {RetryCount} failed. Next retry in {Delay}.", retryCount, timeSpan); }); try @@ -52,35 +49,9 @@ public static WebApplication EnsureDatabaseAvailable(this WebApplication app) } catch (Exception ex) { - logger?.LogError(ex, "Database connectivity could not be established after {Attempts} attempts to {ConnectionPreview}. Verify the database is running and the connection settings (env/.env). Startup will continue; migrations may fail.", maxRetryAttempts, connPreview); + logger?.LogError(ex, "Database connectivity could not be established after {Attempts} attempts. Verify the database is running and the connection settings (env/.env). Startup will continue; migrations may fail.", maxRetryAttempts); } return app; } - - private static string GetRedactedConnectionString(IConfiguration configuration) - { - var conn = configuration.GetConnectionString("DefaultConnection"); - return RedactPassword(conn ?? "(none)"); - } - - 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)"; - } - } } From 3a5d4ae1781922642c8ccfd1b5fbd78b86c8ebc1 Mon Sep 17 00:00:00 2001 From: Kaue Reinbold Date: Sun, 25 Jan 2026 18:08:04 -0300 Subject: [PATCH 2/2] fix(migrations): remove connection string from logs Also remove connection string logging from MigrationsRunner service to maintain consistency across all services. Changes: - Removed RedactConnectionString() helper method - Updated startup log to only show provider name - Log now shows: 'Migration runner starting with provider: {Provider}' --- .../Reminders.MigrationsRunner/Program.cs | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/server/services/dotnet/Reminders.MigrationsRunner/Program.cs b/src/server/services/dotnet/Reminders.MigrationsRunner/Program.cs index 68fd2da..356b055 100644 --- a/src/server/services/dotnet/Reminders.MigrationsRunner/Program.cs +++ b/src/server/services/dotnet/Reminders.MigrationsRunner/Program.cs @@ -54,10 +54,7 @@ migrationStatus = MigrationStatus.Running; startTime = DateTime.UtcNow; - // Redact password from connection string for logging - var redactedConnectionString = RedactConnectionString(connectionString); - logger.LogInformation("Migration runner starting with provider: {Provider}, connection: {Connection}", - provider, redactedConnectionString); + logger.LogInformation("Migration runner starting with provider: {Provider}", provider); using var scope = app.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); @@ -207,24 +204,6 @@ await policy.ExecuteAsync(async () => // Exit with appropriate code Environment.Exit(migrationStatus == MigrationStatus.Completed ? 0 : 1); -// Helper method to redact passwords from connection strings -static string RedactConnectionString(string connectionString) -{ - var parts = connectionString.Split(';', StringSplitOptions.RemoveEmptyEntries); - var redacted = parts.Select(part => - { - var keyValue = part.Split('=', 2); - if (keyValue.Length == 2 && - (keyValue[0].Trim().Equals("Password", StringComparison.OrdinalIgnoreCase) || - keyValue[0].Trim().Equals("Pwd", StringComparison.OrdinalIgnoreCase))) - { - return $"{keyValue[0]}=***"; - } - return part; - }); - return string.Join(";", redacted); -} - // MigrationStatus enum for tracking execution state enum MigrationStatus {