using MarketAlly.AIPlugin; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml.Linq; namespace MarketAlly.AIPlugin.Security.Plugins { /// /// Validates configuration files for security best practices and sensitive data exposure /// [AIPlugin("SecureConfiguration", "Validates configuration files for security best practices and sensitive data exposure")] public class SecureConfigurationPlugin : IAIPlugin { [AIParameter("Full path to the configuration file or directory", required: true)] public string ConfigPath { get; set; } [AIParameter("Check for exposed secrets in config files", required: false)] public bool CheckSecrets { get; set; } = true; [AIParameter("Validate HTTPS/TLS configurations", required: false)] public bool CheckTls { get; set; } = true; [AIParameter("Check database connection security", required: false)] public bool CheckDatabase { get; set; } = true; [AIParameter("Validate CORS settings", required: false)] public bool CheckCors { get; set; } = true; [AIParameter("Check environment-specific configurations", required: false)] public bool CheckEnvironments { get; set; } = true; public IReadOnlyDictionary SupportedParameters => new Dictionary { ["configPath"] = typeof(string), ["checkSecrets"] = typeof(bool), ["checkTls"] = typeof(bool), ["checkDatabase"] = typeof(bool), ["checkCors"] = typeof(bool), ["checkEnvironments"] = typeof(bool) }; // Configuration security patterns private static readonly Dictionary ConfigPatterns = new() { // Exposed Secrets ["password_in_config"] = (new Regex(@"(password|pwd|pass|secret|key|token)\s*[=:]\s*['""][^'""]{3,}['""]", RegexOptions.IgnoreCase), "Secret", "High", "Password or secret in configuration file"), ["connection_string_password"] = (new Regex(@"password\s*=\s*[^;]{3,}", RegexOptions.IgnoreCase), "Secret", "High", "Database password in connection string"), ["api_key_exposed"] = (new Regex(@"(api.?key|apikey|clientsecret)\s*[=:]\s*['""][^'""]{10,}['""]", RegexOptions.IgnoreCase), "Secret", "Critical", "API key or client secret exposed in configuration"), ["jwt_secret_exposed"] = (new Regex(@"(jwt|token).*(secret|key)\s*[=:]\s*['""][^'""]{1,}['""]", RegexOptions.IgnoreCase), "Secret", "Critical", "JWT secret exposed in configuration"), ["encryption_key_exposed"] = (new Regex(@"(encryption|cipher).*(key|secret)\s*[=:]\s*['""][^'""]{1,}['""]", RegexOptions.IgnoreCase), "Secret", "Critical", "Encryption key exposed in configuration"), // TLS/HTTPS Issues ["ssl_disabled"] = (new Regex(@"(ssl|https|tls)\s*[=:]\s*(false|disabled|no)", RegexOptions.IgnoreCase), "TLS", "High", "SSL/TLS disabled in configuration"), ["weak_tls_version"] = (new Regex(@"(tls|ssl).*(version|protocol)\s*[=:]\s*['""]?(1\.0|1\.1|ssl)['""]?", RegexOptions.IgnoreCase), "TLS", "High", "Weak TLS version configured (TLS 1.0/1.1 or SSL)"), ["insecure_ciphers"] = (new Regex(@"(cipher|encryption).*(rc4|des|md5|sha1)", RegexOptions.IgnoreCase), "TLS", "Medium", "Weak cipher suites configured"), ["certificate_validation_disabled"] = (new Regex(@"(certificate|cert).*(validation|verify|check)\s*[=:]\s*(false|disabled|no)", RegexOptions.IgnoreCase), "TLS", "High", "Certificate validation disabled"), // Database Security ["integrated_security_disabled"] = (new Regex(@"integrated.?security\s*=\s*(false|no)", RegexOptions.IgnoreCase), "Database", "Medium", "Integrated security disabled for database connection"), ["sql_server_trust_cert"] = (new Regex(@"trustservercertificate\s*=\s*true", RegexOptions.IgnoreCase), "Database", "Medium", "SQL Server certificate trust enabled (potential MITM risk)"), ["database_timeout_too_long"] = (new Regex(@"(timeout|commandtimeout)\s*=\s*([5-9]\d{2,}|\d{4,})", RegexOptions.IgnoreCase), "Database", "Low", "Very long database timeout configured"), ["database_no_encryption"] = (new Regex(@"encrypt\s*=\s*(false|no)", RegexOptions.IgnoreCase), "Database", "Medium", "Database connection encryption disabled"), // CORS Issues ["cors_allow_all_origins"] = (new Regex(@"(allowedorigins|origins)\s*.*\*", RegexOptions.IgnoreCase), "CORS", "High", "CORS allows all origins (*)"), ["cors_allow_credentials_with_wildcard"] = (new Regex(@"(allowcredentials|credentials)\s*[=:]\s*true.*\*", RegexOptions.IgnoreCase), "CORS", "High", "CORS allows credentials with wildcard origin"), ["cors_unsafe_headers"] = (new Regex(@"(allowedheaders|headers).*\*", RegexOptions.IgnoreCase), "CORS", "Medium", "CORS allows all headers (*)"), ["cors_unsafe_methods"] = (new Regex(@"(allowedmethods|methods).*(delete|put|patch)", RegexOptions.IgnoreCase), "CORS", "Low", "CORS allows potentially unsafe HTTP methods"), // General Security Settings ["debug_mode_enabled"] = (new Regex(@"(debug|development)\s*[=:]\s*true", RegexOptions.IgnoreCase), "General", "Medium", "Debug mode enabled"), ["detailed_errors_enabled"] = (new Regex(@"(detailederrors|customerrors)\s*[=:]\s*(on|true|detailed)", RegexOptions.IgnoreCase), "General", "Medium", "Detailed error information enabled"), ["insecure_cookies"] = (new Regex(@"(httponly|secure)\s*[=:]\s*(false|no)", RegexOptions.IgnoreCase), "General", "Medium", "Insecure cookie settings"), ["weak_session_timeout"] = (new Regex(@"(session|timeout)\s*[=:]\s*['""]?\d{1,2}['""]?", RegexOptions.IgnoreCase), "General", "Low", "Very short session timeout"), // Environment-Specific Issues ["prod_using_dev_settings"] = (new Regex(@"(environment|env)\s*[=:]\s*['""]?(development|dev)['""]?", RegexOptions.IgnoreCase), "Environment", "High", "Production environment using development settings"), ["hardcoded_environment"] = (new Regex(@"(server|host|endpoint)\s*[=:]\s*['""]localhost['""]", RegexOptions.IgnoreCase), "Environment", "Medium", "Hardcoded localhost/development server"), ["missing_environment_config"] = (new Regex(@"\{\{.*\}\}|\$\{.*\}", RegexOptions.IgnoreCase), "Environment", "Low", "Environment variable placeholder found"), // Logging Security ["sensitive_data_logging"] = (new Regex(@"(log|logging).*(password|secret|key|token)", RegexOptions.IgnoreCase), "Logging", "High", "Sensitive data may be logged"), ["excessive_logging"] = (new Regex(@"(loglevel|level)\s*[=:]\s*['""]?(debug|trace|verbose)['""]?", RegexOptions.IgnoreCase), "Logging", "Low", "Excessive logging level in production"), ["log_injection_risk"] = (new Regex(@"log.*user.*input", RegexOptions.IgnoreCase), "Logging", "Medium", "Potential log injection from user input") }; // Positive configuration patterns (good practices) private static readonly Dictionary GoodConfigPatterns = new() { ["environment_variables"] = new Regex(@"\$\{[^}]+\}|%[^%]+%", RegexOptions.IgnoreCase), ["https_enforced"] = new Regex(@"(https|ssl|tls)\s*[=:]\s*(true|enabled|yes)", RegexOptions.IgnoreCase), ["secure_cookies"] = new Regex(@"(httponly|secure)\s*[=:]\s*(true|yes)", RegexOptions.IgnoreCase), ["strong_tls"] = new Regex(@"(tls|ssl).*(1\.2|1\.3)", RegexOptions.IgnoreCase), ["security_headers"] = new Regex(@"(hsts|csp|x-frame-options|x-content-type-options)", RegexOptions.IgnoreCase), ["encrypted_connections"] = new Regex(@"encrypt\s*=\s*true", RegexOptions.IgnoreCase), ["certificate_validation"] = new Regex(@"(certificate|cert).*(validation|verify)\s*[=:]\s*(true|enabled)", RegexOptions.IgnoreCase) }; public async Task ExecuteAsync(IReadOnlyDictionary parameters) { try { // Extract parameters string configPath = parameters["configPath"].ToString(); bool checkSecrets = parameters.TryGetValue("checkSecrets", out var secretsObj) ? Convert.ToBoolean(secretsObj) : true; bool checkTls = parameters.TryGetValue("checkTls", out var tlsObj) ? Convert.ToBoolean(tlsObj) : true; bool checkDatabase = parameters.TryGetValue("checkDatabase", out var dbObj) ? Convert.ToBoolean(dbObj) : true; bool checkCors = parameters.TryGetValue("checkCors", out var corsObj) ? Convert.ToBoolean(corsObj) : true; bool checkEnvironments = parameters.TryGetValue("checkEnvironments", out var envObj) ? Convert.ToBoolean(envObj) : true; // Validate path exists if (!File.Exists(configPath) && !Directory.Exists(configPath)) { return new AIPluginResult( new FileNotFoundException($"Configuration path not found: {configPath}"), "Configuration path not found" ); } // Find configuration files to analyze var configFiles = GetConfigurationFiles(configPath); if (!configFiles.Any()) { return new AIPluginResult( new FileNotFoundException($"No configuration files found in: {configPath}"), "No configuration files found" ); } var results = new SecureConfigurationResults { ConfigPath = configPath, FilesAnalyzed = configFiles.Count }; // Analyze each configuration file foreach (var configFile in configFiles) { await AnalyzeConfigurationFile(configFile, results, checkSecrets, checkTls, checkDatabase, checkCors, checkEnvironments); } // Calculate security rating results.SecurityRating = CalculateSecurityRating(results); // Generate configuration recommendations results.ConfigurationRecommendations = GenerateConfigurationRecommendations(results); return new AIPluginResult(results, $"Configuration security analysis completed. Found {results.GetTotalIssues()} security issues."); } catch (Exception ex) { return new AIPluginResult(ex, $"Configuration security analysis failed: {ex.Message}"); } } /// /// Finds configuration files to analyze /// private List GetConfigurationFiles(string path) { var configFiles = new List(); if (File.Exists(path)) { if (IsConfigurationFile(path)) { configFiles.Add(path); } } else if (Directory.Exists(path)) { // Look for common configuration file patterns var patterns = new[] { "*.json", "*.config", "*.xml", "*.yml", "*.yaml", "*.ini", "*.properties", "*.conf", "*.cfg", "*.env" }; foreach (var pattern in patterns) { configFiles.AddRange(Directory.GetFiles(path, pattern, SearchOption.AllDirectories)); } // Filter to actual configuration files configFiles = configFiles.Where(IsConfigurationFile).ToList(); } // Exclude common non-config directories var excludedDirs = new[] { "node_modules", "bin", "obj", ".git", ".vs", "packages", "target", "build" }; configFiles = configFiles.Where(f => !excludedDirs.Any(dir => f.Contains($"{Path.DirectorySeparatorChar}{dir}{Path.DirectorySeparatorChar}"))).ToList(); return configFiles.Take(20).ToList(); // Limit for performance } /// /// Checks if a file is a configuration file /// private bool IsConfigurationFile(string filePath) { var fileName = Path.GetFileName(filePath).ToLower(); var configNames = new[] { "appsettings", "web.config", "app.config", "config", "settings", "environment", ".env", "database", "connection", "cors", "security" }; return configNames.Any(name => fileName.Contains(name)) || fileName.EndsWith(".json") || fileName.EndsWith(".config") || fileName.EndsWith(".xml") || fileName.EndsWith(".yml") || fileName.EndsWith(".yaml") || fileName.EndsWith(".ini") || fileName.EndsWith(".properties"); } /// /// Analyzes a single configuration file /// private async Task AnalyzeConfigurationFile(string configFile, SecureConfigurationResults results, bool checkSecrets, bool checkTls, bool checkDatabase, bool checkCors, bool checkEnvironments) { try { var content = await File.ReadAllTextAsync(configFile); var fileName = Path.GetFileName(configFile); var extension = Path.GetExtension(configFile).ToLower(); // Parse configuration based on file type var configData = ParseConfigurationFile(content, extension); // Perform security checks if (checkSecrets) { await AnalyzeSecretsExposure(configFile, content, configData, results); } if (checkTls) { await AnalyzeTlsConfiguration(configFile, content, configData, results); } if (checkDatabase) { await AnalyzeDatabaseSecurity(configFile, content, configData, results); } if (checkCors) { await AnalyzeCorsConfiguration(configFile, content, configData, results); } if (checkEnvironments) { await AnalyzeEnvironmentConfiguration(configFile, content, configData, results); } // Check for good practices await AnalyzeGoodPractices(configFile, content, results); } catch (Exception ex) { results.AnalysisErrors.Add($"Error analyzing {configFile}: {ex.Message}"); } } /// /// Parses configuration file content based on format /// private Dictionary ParseConfigurationFile(string content, string extension) { var configData = new Dictionary(); try { switch (extension) { case ".json": if (content.Trim().StartsWith("{")) { var jsonDoc = JsonDocument.Parse(content); configData = JsonElementToDictionary(jsonDoc.RootElement); } break; case ".xml": case ".config": var xmlDoc = XDocument.Parse(content); configData = XmlToDictionary(xmlDoc); break; case ".yml": case ".yaml": // Simple YAML parsing (key: value pairs) configData = ParseSimpleYaml(content); break; case ".ini": case ".properties": configData = ParseKeyValueFile(content); break; } } catch { // If parsing fails, fall back to regex analysis on raw content } return configData; } /// /// Converts JsonElement to Dictionary /// private Dictionary JsonElementToDictionary(JsonElement element) { var dict = new Dictionary(); if (element.ValueKind == JsonValueKind.Object) { foreach (var property in element.EnumerateObject()) { dict[property.Name] = property.Value.ValueKind == JsonValueKind.Object ? JsonElementToDictionary(property.Value) : property.Value.ToString(); } } return dict; } /// /// Converts XML to Dictionary (simplified) /// private Dictionary XmlToDictionary(XDocument doc) { var dict = new Dictionary(); foreach (var element in doc.Descendants()) { if (!element.HasElements) { dict[element.Name.LocalName] = element.Value; } } return dict; } /// /// Parses simple YAML (key: value pairs) /// private Dictionary ParseSimpleYaml(string content) { var dict = new Dictionary(); var lines = content.Split('\n'); foreach (var line in lines) { var trimmed = line.Trim(); if (trimmed.Contains(':') && !trimmed.StartsWith('#')) { var parts = trimmed.Split(':', 2); if (parts.Length == 2) { dict[parts[0].Trim()] = parts[1].Trim(); } } } return dict; } /// /// Parses key=value format files /// private Dictionary ParseKeyValueFile(string content) { var dict = new Dictionary(); var lines = content.Split('\n'); foreach (var line in lines) { var trimmed = line.Trim(); if (trimmed.Contains('=') && !trimmed.StartsWith('#') && !trimmed.StartsWith(';')) { var parts = trimmed.Split('=', 2); if (parts.Length == 2) { dict[parts[0].Trim()] = parts[1].Trim(); } } } return dict; } /// /// Analyzes configuration for exposed secrets /// private async Task AnalyzeSecretsExposure(string filePath, string content, Dictionary configData, SecureConfigurationResults results) { var secretPatterns = ConfigPatterns.Where(p => p.Value.Type == "Secret").ToList(); foreach (var pattern in secretPatterns) { var matches = pattern.Value.Pattern.Matches(content); foreach (Match match in matches) { // Additional validation for false positives if (!IsLikelySecret(match.Value)) continue; results.ExposedSecrets.Add(new ConfigurationIssue { Type = "Exposed Secret", Severity = pattern.Value.Severity, Description = pattern.Value.Description, File = filePath, LineNumber = GetLineNumber(content, match.Index), ConfigKey = ExtractConfigKey(content, match.Index), Value = MaskSensitiveValue(match.Value), Recommendation = GetSecretsRecommendation(pattern.Key) }); } } } /// /// Analyzes TLS/HTTPS configuration /// private async Task AnalyzeTlsConfiguration(string filePath, string content, Dictionary configData, SecureConfigurationResults results) { var tlsPatterns = ConfigPatterns.Where(p => p.Value.Type == "TLS").ToList(); foreach (var pattern in tlsPatterns) { var matches = pattern.Value.Pattern.Matches(content); foreach (Match match in matches) { results.SecurityIssues.Add(new ConfigurationIssue { Type = "TLS/HTTPS Security", Severity = pattern.Value.Severity, Description = pattern.Value.Description, File = filePath, LineNumber = GetLineNumber(content, match.Index), ConfigKey = ExtractConfigKey(content, match.Index), Value = match.Value, Recommendation = GetTlsRecommendation(pattern.Key) }); } } } /// /// Analyzes database security configuration /// private async Task AnalyzeDatabaseSecurity(string filePath, string content, Dictionary configData, SecureConfigurationResults results) { var dbPatterns = ConfigPatterns.Where(p => p.Value.Type == "Database").ToList(); foreach (var pattern in dbPatterns) { var matches = pattern.Value.Pattern.Matches(content); foreach (Match match in matches) { results.SecurityIssues.Add(new ConfigurationIssue { Type = "Database Security", Severity = pattern.Value.Severity, Description = pattern.Value.Description, File = filePath, LineNumber = GetLineNumber(content, match.Index), ConfigKey = ExtractConfigKey(content, match.Index), Value = MaskSensitiveValue(match.Value), Recommendation = GetDatabaseRecommendation(pattern.Key) }); } } } /// /// Analyzes CORS configuration /// private async Task AnalyzeCorsConfiguration(string filePath, string content, Dictionary configData, SecureConfigurationResults results) { var corsPatterns = ConfigPatterns.Where(p => p.Value.Type == "CORS").ToList(); foreach (var pattern in corsPatterns) { var matches = pattern.Value.Pattern.Matches(content); foreach (Match match in matches) { results.SecurityIssues.Add(new ConfigurationIssue { Type = "CORS Security", Severity = pattern.Value.Severity, Description = pattern.Value.Description, File = filePath, LineNumber = GetLineNumber(content, match.Index), ConfigKey = ExtractConfigKey(content, match.Index), Value = match.Value, Recommendation = GetCorsRecommendation(pattern.Key) }); } } } /// /// Analyzes environment-specific configuration /// private async Task AnalyzeEnvironmentConfiguration(string filePath, string content, Dictionary configData, SecureConfigurationResults results) { var envPatterns = ConfigPatterns.Where(p => p.Value.Type == "Environment" || p.Value.Type == "General" || p.Value.Type == "Logging").ToList(); foreach (var pattern in envPatterns) { var matches = pattern.Value.Pattern.Matches(content); foreach (Match match in matches) { var severity = pattern.Value.Severity; // Adjust severity for environment-specific issues if (pattern.Value.Type == "Environment" && IsProductionConfig(filePath)) { severity = severity == "Medium" ? "High" : severity; } results.EnvironmentIssues.Add(new ConfigurationIssue { Type = pattern.Value.Type, Severity = severity, Description = pattern.Value.Description, File = filePath, LineNumber = GetLineNumber(content, match.Index), ConfigKey = ExtractConfigKey(content, match.Index), Value = match.Value, Recommendation = GetEnvironmentRecommendation(pattern.Key) }); } } } /// /// Analyzes good security practices in configuration /// private async Task AnalyzeGoodPractices(string filePath, string content, SecureConfigurationResults results) { foreach (var pattern in GoodConfigPatterns) { if (pattern.Value.IsMatch(content)) { var practiceDescription = GetGoodPracticeDescription(pattern.Key); if (!results.GoodPractices.Contains(practiceDescription)) { results.GoodPractices.Add(practiceDescription); } } } } /// /// Checks if a match is likely a real secret /// private bool IsLikelySecret(string value) { // Filter out common non-secrets var nonSecrets = new[] { "password", "secret", "key", "token", "example", "placeholder", "your_", "xxx", "***", "localhost", "127.0.0.1" }; var lowerValue = value.ToLower(); if (nonSecrets.Any(ns => lowerValue.Contains(ns))) return false; // Check for reasonable length and complexity var cleanValue = value.Replace("\"", "").Replace("'", "").Trim(); return cleanValue.Length >= 8 && cleanValue.Any(char.IsLetterOrDigit); } /// /// Checks if configuration file is for production environment /// private bool IsProductionConfig(string filePath) { var fileName = Path.GetFileName(filePath).ToLower(); return fileName.Contains("prod") || fileName.Contains("production") || fileName.Contains("release"); } /// /// Extracts configuration key from context /// private string ExtractConfigKey(string content, int index) { var lines = content.Split('\n'); var lineNumber = GetLineNumber(content, index) - 1; if (lineNumber >= 0 && lineNumber < lines.Length) { var line = lines[lineNumber]; var colonIndex = line.IndexOf(':'); var equalsIndex = line.IndexOf('='); if (colonIndex > 0 && (equalsIndex < 0 || colonIndex < equalsIndex)) { return line.Substring(0, colonIndex).Trim().Trim('"', '\''); } else if (equalsIndex > 0) { return line.Substring(0, equalsIndex).Trim().Trim('"', '\''); } } return "unknown"; } /// /// Masks sensitive values for display /// private string MaskSensitiveValue(string value) { if (value.Length <= 4) return "***"; return value.Substring(0, 2) + "***" + value.Substring(value.Length - 2); } /// /// Gets line number for character index /// private int GetLineNumber(string content, int index) { return content.Take(index).Count(c => c == '\n') + 1; } /// /// Gets secrets-specific recommendations /// private string GetSecretsRecommendation(string patternKey) { return patternKey switch { "password_in_config" => "Move passwords to environment variables or secure key management systems like Azure Key Vault or AWS Secrets Manager.", "connection_string_password" => "Use integrated authentication or move connection strings to secure configuration providers.", "api_key_exposed" => "Store API keys in environment variables and use secure configuration providers.", "jwt_secret_exposed" => "Move JWT secrets to environment variables and ensure they are cryptographically strong.", "encryption_key_exposed" => "Store encryption keys in dedicated key management systems, never in configuration files.", _ => "Move all secrets to environment variables or dedicated secret management systems." }; } /// /// Gets TLS-specific recommendations /// private string GetTlsRecommendation(string patternKey) { return patternKey switch { "ssl_disabled" => "Enable HTTPS/TLS for all production environments to protect data in transit.", "weak_tls_version" => "Use TLS 1.2 or 1.3. Disable older protocols (TLS 1.0/1.1, SSL 2.0/3.0).", "insecure_ciphers" => "Configure strong cipher suites and disable weak algorithms like RC4, DES, MD5.", "certificate_validation_disabled" => "Enable certificate validation to prevent man-in-the-middle attacks.", _ => "Implement strong TLS configuration with modern protocols and cipher suites." }; } /// /// Gets database-specific recommendations /// private string GetDatabaseRecommendation(string patternKey) { return patternKey switch { "integrated_security_disabled" => "Use integrated security (Windows Authentication) when possible for better security.", "sql_server_trust_cert" => "Verify server certificates properly instead of blindly trusting them.", "database_timeout_too_long" => "Use reasonable database timeouts to prevent resource exhaustion.", "database_no_encryption" => "Enable encryption for database connections, especially over networks.", _ => "Follow database security best practices including encrypted connections and proper authentication." }; } /// /// Gets CORS-specific recommendations /// private string GetCorsRecommendation(string patternKey) { return patternKey switch { "cors_allow_all_origins" => "Specify explicit allowed origins instead of using wildcards (*) in production.", "cors_allow_credentials_with_wildcard" => "Never allow credentials with wildcard origins - specify exact domains.", "cors_unsafe_headers" => "Specify only required headers instead of allowing all headers (*).", "cors_unsafe_methods" => "Review if unsafe HTTP methods (DELETE, PUT, PATCH) are necessary for CORS.", _ => "Configure CORS with specific, minimal permissions based on actual requirements." }; } /// /// Gets environment-specific recommendations /// private string GetEnvironmentRecommendation(string patternKey) { return patternKey switch { "prod_using_dev_settings" => "Ensure production environments use production-specific configuration, not development settings.", "debug_mode_enabled" => "Disable debug mode in production to prevent information disclosure.", "detailed_errors_enabled" => "Disable detailed error messages in production to prevent information leakage.", "hardcoded_environment" => "Use environment-specific configuration instead of hardcoded development values.", "sensitive_data_logging" => "Ensure sensitive data is not logged. Use structured logging with data classification.", "excessive_logging" => "Use appropriate logging levels in production (Info/Warning/Error, not Debug/Trace).", _ => "Review environment-specific settings and ensure appropriate configuration for each environment." }; } /// /// Gets description for good practices /// private string GetGoodPracticeDescription(string patternKey) { return patternKey switch { "environment_variables" => "Uses environment variables for configuration", "https_enforced" => "Enforces HTTPS/TLS encryption", "secure_cookies" => "Uses secure cookie settings", "strong_tls" => "Uses modern TLS versions (1.2/1.3)", "security_headers" => "Implements security headers", "encrypted_connections" => "Uses encrypted database connections", "certificate_validation" => "Enables proper certificate validation", _ => $"Implements {patternKey} security feature" }; } /// /// Calculates overall security rating /// private string CalculateSecurityRating(SecureConfigurationResults results) { var totalIssues = results.GetTotalIssues(); var criticalIssues = results.ExposedSecrets.Count(s => s.Severity == "Critical") + results.SecurityIssues.Count(s => s.Severity == "Critical") + results.EnvironmentIssues.Count(s => s.Severity == "Critical"); var highIssues = results.ExposedSecrets.Count(s => s.Severity == "High") + results.SecurityIssues.Count(s => s.Severity == "High") + results.EnvironmentIssues.Count(s => s.Severity == "High"); if (criticalIssues > 0) return "Critical Risk"; else if (highIssues >= 3) return "High Risk"; else if (totalIssues >= 5) return "Medium Risk"; else if (totalIssues > 0) return "Low Risk"; else return "Secure"; } /// /// Generates configuration recommendations /// private List GenerateConfigurationRecommendations(SecureConfigurationResults results) { var recommendations = new List(); // Critical secrets exposure var criticalSecrets = results.ExposedSecrets.Where(s => s.Severity == "Critical").ToList(); if (criticalSecrets.Any()) { recommendations.Add("🚨 **CRITICAL: SECRETS EXPOSED**:"); recommendations.Add($" • {criticalSecrets.Count} critical secrets found in configuration files"); recommendations.Add(" • Immediately move secrets to environment variables or key vaults"); recommendations.Add(" • Rotate any exposed secrets/keys immediately"); recommendations.Add(" • Review commit history for accidentally committed secrets"); } // High severity issues var highSecrets = results.ExposedSecrets.Where(s => s.Severity == "High").ToList(); if (highSecrets.Any()) { recommendations.Add("⚠️ **HIGH PRIORITY: SECRET MANAGEMENT**:"); recommendations.Add($" • {highSecrets.Count} high-risk secrets found"); recommendations.Add(" • Implement proper secret management strategy"); recommendations.Add(" • Use Azure Key Vault, AWS Secrets Manager, or similar services"); } // TLS/HTTPS issues var tlsIssues = results.SecurityIssues.Where(i => i.Type.Contains("TLS")).ToList(); if (tlsIssues.Any()) { recommendations.Add("🔒 **TLS/HTTPS SECURITY**:"); recommendations.Add($" • {tlsIssues.Count} TLS security issues found"); recommendations.Add(" • Enable HTTPS enforcement for all environments"); recommendations.Add(" • Use TLS 1.2 or 1.3, disable older protocols"); recommendations.Add(" • Configure strong cipher suites"); } // Database security var dbIssues = results.SecurityIssues.Where(i => i.Type.Contains("Database")).ToList(); if (dbIssues.Any()) { recommendations.Add("🗄️ **DATABASE SECURITY**:"); recommendations.Add($" • {dbIssues.Count} database security issues found"); recommendations.Add(" • Enable connection encryption"); recommendations.Add(" • Use integrated authentication where possible"); recommendations.Add(" • Move connection strings to secure configuration"); } // CORS issues var corsIssues = results.SecurityIssues.Where(i => i.Type.Contains("CORS")).ToList(); if (corsIssues.Any()) { recommendations.Add("🌐 **CORS CONFIGURATION**:"); recommendations.Add($" • {corsIssues.Count} CORS security issues found"); recommendations.Add(" • Specify explicit allowed origins (avoid wildcards)"); recommendations.Add(" • Review allowed headers and methods"); recommendations.Add(" • Never allow credentials with wildcard origins"); } // Environment issues if (results.EnvironmentIssues.Any()) { recommendations.Add("⚙️ **ENVIRONMENT CONFIGURATION**:"); var envByType = results.EnvironmentIssues.GroupBy(i => i.Type).ToList(); foreach (var group in envByType.Take(3)) { recommendations.Add($" • {group.Key}: {group.Count()} issues"); } recommendations.Add(" • Ensure production uses production-specific settings"); recommendations.Add(" • Disable debug mode and detailed errors in production"); } // General best practices recommendations.Add("📋 **CONFIGURATION BEST PRACTICES**:"); recommendations.Add(" • Use environment variables for all sensitive values"); recommendations.Add(" • Implement configuration validation on startup"); recommendations.Add(" • Use different configuration files for each environment"); recommendations.Add(" • Enable security headers (HSTS, CSP, X-Frame-Options)"); recommendations.Add(" • Implement proper logging without sensitive data"); recommendations.Add(" • Regular security configuration reviews"); // Positive reinforcement if (results.GoodPractices.Any()) { recommendations.Add("✅ **GOOD PRACTICES FOUND**:"); foreach (var practice in results.GoodPractices.Take(5)) { recommendations.Add($" • {practice}"); } } // Overall security rating recommendations switch (results.SecurityRating) { case "Critical Risk": recommendations.Add("🚨 **IMMEDIATE ACTION REQUIRED**: Critical security vulnerabilities found"); recommendations.Add(" • Stop deployment until critical issues are resolved"); recommendations.Add(" • Conduct emergency security review"); break; case "High Risk": recommendations.Add("⚠️ **HIGH PRIORITY**: Significant security improvements needed"); recommendations.Add(" • Address high-severity issues before next deployment"); break; case "Medium Risk": recommendations.Add("👍 **GOOD**: Address remaining issues to improve security posture"); break; case "Low Risk": recommendations.Add("🌟 **EXCELLENT**: Minor improvements needed"); break; case "Secure": recommendations.Add("🏆 **OUTSTANDING**: Configuration follows security best practices!"); recommendations.Add(" • Continue regular security reviews"); break; } return recommendations; } } /// /// Results of secure configuration analysis /// public class SecureConfigurationResults { public string ConfigPath { get; set; } public int FilesAnalyzed { get; set; } public List ExposedSecrets { get; set; } = new List(); public List SecurityIssues { get; set; } = new List(); public List EnvironmentIssues { get; set; } = new List(); public List GoodPractices { get; set; } = new List(); public List ConfigurationRecommendations { get; set; } = new List(); public List AnalysisErrors { get; set; } = new List(); public string SecurityRating { get; set; } public int GetTotalIssues() => ExposedSecrets.Count + SecurityIssues.Count + EnvironmentIssues.Count; } /// /// Represents a configuration security issue /// public class ConfigurationIssue { public string Type { get; set; } public string Severity { get; set; } public string Description { get; set; } public string File { get; set; } public int LineNumber { get; set; } public string ConfigKey { get; set; } public string Value { get; set; } public string Recommendation { get; set; } } }