🔒 SECURITY: Emergency fixes and hardening
EMERGENCY FIXES: ✅ DELETE MockSilverPayService.cs - removed fake payment system ✅ REMOVE mock service registration - no fake payments possible ✅ GENERATE new JWT secret - replaced hardcoded key ✅ FIX HttpClient disposal - proper resource management SECURITY HARDENING: ✅ ADD production guards - prevent mock services in production ✅ CREATE environment configs - separate dev/prod settings ✅ ADD config validation - fail fast on misconfiguration IMPACT: - Mock payment system completely eliminated - JWT authentication now uses secure keys - Production deployment now validated on startup - Resource leaks fixed in TeleBot currency API 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
161
LittleShop/Services/ConfigurationValidationService.cs
Normal file
161
LittleShop/Services/ConfigurationValidationService.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace LittleShop.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Validates critical configuration settings on startup to prevent security issues
|
||||
/// </summary>
|
||||
public class ConfigurationValidationService
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private readonly ILogger<ConfigurationValidationService> _logger;
|
||||
|
||||
public ConfigurationValidationService(
|
||||
IConfiguration configuration,
|
||||
IWebHostEnvironment environment,
|
||||
ILogger<ConfigurationValidationService> logger)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_environment = environment;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates all critical configuration settings on startup
|
||||
/// Throws exceptions for security-critical misconfigurations
|
||||
/// </summary>
|
||||
public void ValidateConfiguration()
|
||||
{
|
||||
_logger.LogInformation("🔍 Validating application configuration...");
|
||||
|
||||
ValidateJwtConfiguration();
|
||||
ValidateSilverPayConfiguration();
|
||||
ValidateProductionSafeguards();
|
||||
ValidateEnvironmentConfiguration();
|
||||
|
||||
_logger.LogInformation("✅ Configuration validation completed successfully");
|
||||
}
|
||||
|
||||
private void ValidateJwtConfiguration()
|
||||
{
|
||||
var jwtKey = _configuration["Jwt:Key"];
|
||||
|
||||
if (string.IsNullOrEmpty(jwtKey))
|
||||
{
|
||||
throw new InvalidOperationException("🚨 CRITICAL: JWT Key not configured. Set Jwt:Key in appsettings.json");
|
||||
}
|
||||
|
||||
// Check for the old hardcoded key
|
||||
if (jwtKey.Contains("ThisIsASuperSecretKey"))
|
||||
{
|
||||
throw new InvalidOperationException("🚨 CRITICAL: Default JWT key detected. Generate a new secure key!");
|
||||
}
|
||||
|
||||
// Require minimum key length for security
|
||||
if (jwtKey.Length < 32)
|
||||
{
|
||||
throw new InvalidOperationException("🚨 CRITICAL: JWT key too short. Must be at least 32 characters.");
|
||||
}
|
||||
|
||||
_logger.LogInformation("✅ JWT configuration validated");
|
||||
}
|
||||
|
||||
private void ValidateSilverPayConfiguration()
|
||||
{
|
||||
var baseUrl = _configuration["SilverPay:BaseUrl"];
|
||||
var apiKey = _configuration["SilverPay:ApiKey"];
|
||||
|
||||
if (string.IsNullOrEmpty(baseUrl))
|
||||
{
|
||||
throw new InvalidOperationException("🚨 CRITICAL: SilverPay BaseUrl not configured");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
throw new InvalidOperationException("🚨 CRITICAL: SilverPay ApiKey not configured");
|
||||
}
|
||||
|
||||
// Check for test/mock indicators in production
|
||||
if (_environment.IsProduction())
|
||||
{
|
||||
if (baseUrl.Contains("localhost") || baseUrl.Contains("127.0.0.1"))
|
||||
{
|
||||
throw new InvalidOperationException("🚨 CRITICAL: SilverPay configured with localhost in production!");
|
||||
}
|
||||
|
||||
if (apiKey.Contains("test") || apiKey.Contains("mock") || apiKey.Contains("demo"))
|
||||
{
|
||||
_logger.LogWarning("⚠️ WARNING: SilverPay API key contains test/mock indicators in production");
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("✅ SilverPay configuration validated");
|
||||
}
|
||||
|
||||
private void ValidateProductionSafeguards()
|
||||
{
|
||||
// Ensure no mock services can be accidentally enabled
|
||||
var mockServiceConfig = _configuration.GetSection("SilverPay").GetChildren()
|
||||
.Where(x => x.Key.ToLower().Contains("mock") || x.Key.ToLower().Contains("test"))
|
||||
.ToList();
|
||||
|
||||
if (mockServiceConfig.Any())
|
||||
{
|
||||
foreach (var config in mockServiceConfig)
|
||||
{
|
||||
_logger.LogWarning("⚠️ Found mock/test configuration: {Key} = {Value}", config.Key, config.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// In production, absolutely no mock configurations should exist
|
||||
if (_environment.IsProduction())
|
||||
{
|
||||
var useMockService = _configuration.GetValue<bool>("SilverPay:UseMockService", false);
|
||||
if (useMockService)
|
||||
{
|
||||
throw new InvalidOperationException("🚨 CRITICAL: Mock service enabled in production! Set SilverPay:UseMockService to false");
|
||||
}
|
||||
|
||||
// Check for any configuration that might enable testing/mocking
|
||||
var dangerousConfigs = new[]
|
||||
{
|
||||
"Testing:Enabled",
|
||||
"Mock:Enabled",
|
||||
"Development:MockPayments",
|
||||
"Debug:MockServices"
|
||||
};
|
||||
|
||||
foreach (var configKey in dangerousConfigs)
|
||||
{
|
||||
if (_configuration.GetValue<bool>(configKey, false))
|
||||
{
|
||||
throw new InvalidOperationException($"🚨 CRITICAL: Dangerous test configuration enabled in production: {configKey}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("✅ Production safeguards validated");
|
||||
}
|
||||
|
||||
private void ValidateEnvironmentConfiguration()
|
||||
{
|
||||
// Log current environment for verification
|
||||
_logger.LogInformation("🌍 Environment: {Environment}", _environment.EnvironmentName);
|
||||
|
||||
// Validate database connection
|
||||
var connectionString = _configuration.GetConnectionString("DefaultConnection");
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
{
|
||||
throw new InvalidOperationException("🚨 CRITICAL: Database connection string not configured");
|
||||
}
|
||||
|
||||
// Check for development database in production
|
||||
if (_environment.IsProduction() && connectionString.Contains("littleshop.db"))
|
||||
{
|
||||
_logger.LogWarning("⚠️ WARNING: Using SQLite database in production. Consider PostgreSQL/SQL Server for production.");
|
||||
}
|
||||
|
||||
_logger.LogInformation("✅ Environment configuration validated");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user