MarketAlly.AIPlugin.Extensions/MarketAlly.AIPlugin.Security/Core/SecurityAnalysisOrchestrato...

473 lines
20 KiB
C#
Executable File

using MarketAlly.AIPlugin;
using MarketAlly.AIPlugin.Security.Configuration;
using MarketAlly.AIPlugin.Security.Plugins;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MarketAlly.AIPlugin.Security.Core
{
/// <summary>
/// Orchestrates comprehensive security analysis using multiple security plugins
/// </summary>
public class SecurityAnalysisOrchestrator
{
private readonly ILogger<SecurityAnalysisOrchestrator> _logger;
private readonly SecurityAnalysisConfiguration _configuration;
private readonly List<IAIPlugin> _securityPlugins;
public SecurityAnalysisOrchestrator(SecurityAnalysisConfiguration configuration = null, ILogger<SecurityAnalysisOrchestrator> logger = null)
{
_configuration = configuration ?? SecurityAnalysisConfiguration.GetDefault();
_logger = logger;
_securityPlugins = InitializePlugins();
}
/// <summary>
/// Runs comprehensive security analysis on the specified target
/// </summary>
public async Task<ComprehensiveSecurityReport> RunFullSecurityAnalysis(
string targetPath,
SecurityAnalysisOptions options,
CancellationToken cancellationToken = default)
{
var stopwatch = Stopwatch.StartNew();
var report = new ComprehensiveSecurityReport
{
TargetPath = targetPath,
AnalysisStartTime = DateTime.UtcNow,
Options = options
};
try
{
_logger?.LogInformation("Starting comprehensive security analysis for {TargetPath}", targetPath);
// Validate inputs
ValidateInputs(targetPath, options);
// Run security scans in parallel or sequentially based on configuration
var analysisResults = await ExecuteSecurityAnalysis(targetPath, options, cancellationToken);
// Aggregate results
report = AggregateResults(report, analysisResults);
// Calculate overall metrics
CalculateOverallMetrics(report);
stopwatch.Stop();
report.AnalysisEndTime = DateTime.UtcNow;
report.AnalysisDuration = stopwatch.Elapsed;
_logger?.LogInformation("Security analysis completed in {Duration}ms. Found {TotalIssues} total issues",
stopwatch.ElapsedMilliseconds, report.TotalIssuesFound);
return report;
}
catch (Exception ex)
{
stopwatch.Stop();
report.AnalysisEndTime = DateTime.UtcNow;
report.AnalysisDuration = stopwatch.Elapsed;
report.AnalysisErrors.Add($"Analysis failed: {ex.Message}");
_logger?.LogError(ex, "Security analysis failed for {TargetPath}", targetPath);
throw;
}
}
/// <summary>
/// Runs specific security analysis plugin
/// </summary>
public async Task<AIPluginResult> RunSpecificAnalysis<T>(
string targetPath,
Dictionary<string, object> parameters,
CancellationToken cancellationToken = default) where T : IAIPlugin, new()
{
var plugin = new T();
_logger?.LogInformation("Running {PluginType} analysis for {TargetPath}", typeof(T).Name, targetPath);
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(_configuration.Performance.TimeoutSeconds));
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
try
{
var result = await plugin.ExecuteAsync(parameters);
_logger?.LogInformation("Completed {PluginType} analysis. Success: {Success}",
typeof(T).Name, result.Success);
return result;
}
catch (OperationCanceledException) when (timeoutCts.Token.IsCancellationRequested)
{
_logger?.LogWarning("Security analysis timed out for {PluginType}", typeof(T).Name);
throw new TimeoutException($"Security analysis timed out after {_configuration.Performance.TimeoutSeconds} seconds");
}
}
private List<IAIPlugin> InitializePlugins()
{
return new List<IAIPlugin>
{
new SecurityScanPlugin(),
new AuthenticationAnalyzerPlugin(),
new InputValidationPlugin(),
new VulnerabilityAnalyzerPlugin(),
new SecureConfigurationPlugin()
};
}
private void ValidateInputs(string targetPath, SecurityAnalysisOptions options)
{
if (string.IsNullOrWhiteSpace(targetPath))
throw new ArgumentException("Target path cannot be null or empty", nameof(targetPath));
if (options == null)
throw new ArgumentNullException(nameof(options));
// Additional validation based on configuration
var validationResult = _configuration.Validate();
if (!validationResult.IsValid)
{
throw new InvalidOperationException($"Invalid configuration: {string.Join(", ", validationResult.Errors)}");
}
}
private async Task<Dictionary<string, AIPluginResult>> ExecuteSecurityAnalysis(
string targetPath,
SecurityAnalysisOptions options,
CancellationToken cancellationToken)
{
var results = new Dictionary<string, AIPluginResult>();
var analysisTasksb = new List<Task<(string pluginName, AIPluginResult result)>>();
// Security Scan Plugin
if (options.ScanSecrets || options.ScanVulnerabilities)
{
var plugin = new SecurityScanPlugin
{
Path = targetPath,
ScanSecrets = options.ScanSecrets,
ScanSqlInjection = options.ScanVulnerabilities,
ScanXss = options.ScanVulnerabilities,
ScanConfigurations = options.ScanConfiguration,
SeverityLevel = _configuration.ScanSettings.DefaultSeverityLevel
};
var task = ExecutePluginWithTimeout(
"SecurityScan",
() => plugin.ExecuteAsync(new Dictionary<string, object>()),
cancellationToken);
analysisTasksb.Add(task);
}
// Authentication Analyzer Plugin
if (options.ScanAuthentication)
{
var plugin = new AuthenticationAnalyzerPlugin
{
Path = targetPath,
CheckJwt = true,
CheckOAuth = true,
CheckSessions = true,
CheckAuthorization = true,
CheckPasswords = true
};
var task = ExecutePluginWithTimeout(
"AuthenticationAnalyzer",
() => plugin.ExecuteAsync(new Dictionary<string, object>()),
cancellationToken);
analysisTasksb.Add(task);
}
// Input Validation Plugin
if (options.ScanInputValidation)
{
var plugin = new InputValidationPlugin
{
FilePath = targetPath,
CheckSqlInjection = true,
CheckXssProtection = true,
CheckCsrfProtection = true,
AnalyzeSanitization = true,
GenerateSuggestions = true
};
var task = ExecutePluginWithTimeout(
"InputValidation",
() => plugin.ExecuteAsync(new Dictionary<string, object>()),
cancellationToken);
analysisTasksb.Add(task);
}
// Vulnerability Analyzer Plugin
if (options.ScanDependencies)
{
var plugin = new VulnerabilityAnalyzerPlugin
{
ProjectPath = targetPath,
IncludeTransitive = true,
CheckOutdated = true,
VulnerabilitySource = "nvd",
GenerateRecommendations = true
};
var task = ExecutePluginWithTimeout(
"VulnerabilityAnalyzer",
() => plugin.ExecuteAsync(new Dictionary<string, object>()),
cancellationToken);
analysisTasksb.Add(task);
}
// Secure Configuration Plugin
if (options.ScanConfiguration)
{
var plugin = new SecureConfigurationPlugin
{
ConfigPath = targetPath,
CheckSecrets = true,
CheckTls = true,
CheckDatabase = true,
CheckCors = true,
CheckEnvironments = true
};
var task = ExecutePluginWithTimeout(
"SecureConfiguration",
() => plugin.ExecuteAsync(new Dictionary<string, object>()),
cancellationToken);
analysisTasksb.Add(task);
}
// Execute all analysis tasks
var completedTasks = await Task.WhenAll(analysisTasksb);
foreach (var (pluginName, result) in completedTasks)
{
results[pluginName] = result;
}
return results;
}
private async Task<(string pluginName, AIPluginResult result)> ExecutePluginWithTimeout(
string pluginName,
Func<Task<AIPluginResult>> pluginExecution,
CancellationToken cancellationToken)
{
try
{
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(_configuration.Performance.TimeoutSeconds));
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
var result = await pluginExecution();
return (pluginName, result);
}
catch (OperationCanceledException)
{
_logger?.LogWarning("Plugin {PluginName} timed out", pluginName);
return (pluginName, new AIPluginResult(
new TimeoutException($"Plugin {pluginName} timed out"),
$"Plugin {pluginName} analysis timed out"));
}
catch (Exception ex)
{
_logger?.LogError(ex, "Plugin {PluginName} failed", pluginName);
return (pluginName, new AIPluginResult(ex, $"Plugin {pluginName} failed: {ex.Message}"));
}
}
private ComprehensiveSecurityReport AggregateResults(
ComprehensiveSecurityReport report,
Dictionary<string, AIPluginResult> analysisResults)
{
foreach (var kvp in analysisResults)
{
var pluginName = kvp.Key;
var result = kvp.Value;
if (!result.Success)
{
report.AnalysisErrors.Add($"{pluginName}: {result.Message}");
continue;
}
// Extract and assign plugin-specific results
switch (pluginName)
{
case "SecurityScan":
report.SecurityScanResults = result.Data as SecurityScanResults;
break;
case "AuthenticationAnalyzer":
report.AuthenticationResults = result.Data as AuthenticationAnalysisResults;
break;
case "InputValidation":
report.InputValidationResults = result.Data as InputValidationResults;
break;
case "VulnerabilityAnalyzer":
report.VulnerabilityResults = result.Data as VulnerabilityAnalysisResults;
break;
case "SecureConfiguration":
report.ConfigurationResults = result.Data as SecureConfigurationResults;
break;
}
}
return report;
}
private void CalculateOverallMetrics(ComprehensiveSecurityReport report)
{
// Calculate total issues
var totalIssues = 0;
totalIssues += report.SecurityScanResults?.GetTotalIssues() ?? 0;
totalIssues += report.AuthenticationResults?.GetTotalIssues() ?? 0;
totalIssues += report.InputValidationResults?.GetTotalIssues() ?? 0;
totalIssues += report.VulnerabilityResults?.VulnerablePackages.Count ?? 0;
totalIssues += report.ConfigurationResults?.GetTotalIssues() ?? 0;
report.TotalIssuesFound = totalIssues;
// Calculate risk scores
var riskScores = new List<int>();
if (report.SecurityScanResults != null) riskScores.Add(report.SecurityScanResults.OverallRiskScore);
if (report.AuthenticationResults != null) riskScores.Add(report.AuthenticationResults.ComplianceScore);
if (report.InputValidationResults != null) riskScores.Add(report.InputValidationResults.SecurityScore);
if (report.VulnerabilityResults != null) riskScores.Add(Math.Max(0, 100 - report.VulnerabilityResults.RiskScore));
report.OverallRiskScore = riskScores.Any() ? (int)riskScores.Average() : 100;
report.OverallRiskLevel = CalculateRiskLevel(report.OverallRiskScore, totalIssues);
// Generate comprehensive recommendations
report.OverallRecommendations = GenerateOverallRecommendations(report);
}
private string CalculateRiskLevel(int riskScore, int totalIssues)
{
if (totalIssues == 0) return "Very Low";
if (riskScore >= 80) return "Low";
if (riskScore >= 60) return "Medium";
if (riskScore >= 40) return "High";
return "Critical";
}
private List<string> GenerateOverallRecommendations(ComprehensiveSecurityReport report)
{
var recommendations = new List<string>();
// Critical issues first
var criticalIssues = new List<string>();
if (report.SecurityScanResults?.Secrets.Any(s => s.Severity == "Critical") == true)
criticalIssues.Add("Critical secrets exposed in code");
if (report.AuthenticationResults?.AuthenticationIssues.Any(a => a.Severity == "Critical") == true)
criticalIssues.Add("Critical authentication vulnerabilities");
if (criticalIssues.Any())
{
recommendations.Add("🚨 **IMMEDIATE ACTION REQUIRED**:");
recommendations.AddRange(criticalIssues.Select(issue => $" • {issue}"));
}
// Overall security posture
switch (report.OverallRiskLevel)
{
case "Critical":
recommendations.Add("🚨 **CRITICAL SECURITY RISK**: Immediate remediation required before deployment");
break;
case "High":
recommendations.Add("⚠️ **HIGH SECURITY RISK**: Address critical issues within 24 hours");
break;
case "Medium":
recommendations.Add("⚡ **MEDIUM SECURITY RISK**: Plan remediation within current sprint");
break;
case "Low":
recommendations.Add("👍 **LOW SECURITY RISK**: Continue monitoring and improvement");
break;
case "Very Low":
recommendations.Add("✅ **EXCELLENT SECURITY POSTURE**: Maintain current practices");
break;
}
// Add plugin-specific top recommendations
AddTopRecommendations(recommendations, report);
return recommendations;
}
private void AddTopRecommendations(List<string> recommendations, ComprehensiveSecurityReport report)
{
recommendations.Add("📋 **TOP SECURITY PRIORITIES**:");
if (report.SecurityScanResults?.Secrets.Any() == true)
recommendations.Add(" • Implement secure secret management (Azure Key Vault, AWS Secrets Manager)");
if (report.InputValidationResults?.ValidationIssues.Any() == true)
recommendations.Add(" • Strengthen input validation and sanitization");
if (report.AuthenticationResults?.AuthenticationIssues.Any() == true)
recommendations.Add(" • Review and enhance authentication mechanisms");
if (report.VulnerabilityResults?.VulnerablePackages.Any() == true)
recommendations.Add(" • Update vulnerable dependencies to secure versions");
if (report.ConfigurationResults?.ExposedSecrets.Any() == true)
recommendations.Add(" • Secure configuration management and environment separation");
recommendations.Add(" • Implement security scanning in CI/CD pipeline");
recommendations.Add(" • Regular security training for development team");
}
}
/// <summary>
/// Options for configuring security analysis
/// </summary>
public class SecurityAnalysisOptions
{
public bool ScanSecrets { get; set; } = true;
public bool ScanVulnerabilities { get; set; } = true;
public bool ScanAuthentication { get; set; } = true;
public bool ScanInputValidation { get; set; } = true;
public bool ScanConfiguration { get; set; } = true;
public bool ScanDependencies { get; set; } = true;
public bool GenerateRecommendations { get; set; } = true;
public string SeverityFilter { get; set; } = "low";
}
/// <summary>
/// Comprehensive security analysis report
/// </summary>
public class ComprehensiveSecurityReport
{
public string TargetPath { get; set; }
public DateTime AnalysisStartTime { get; set; }
public DateTime AnalysisEndTime { get; set; }
public TimeSpan AnalysisDuration { get; set; }
public SecurityAnalysisOptions Options { get; set; }
// Plugin Results
public SecurityScanResults SecurityScanResults { get; set; }
public AuthenticationAnalysisResults AuthenticationResults { get; set; }
public InputValidationResults InputValidationResults { get; set; }
public VulnerabilityAnalysisResults VulnerabilityResults { get; set; }
public SecureConfigurationResults ConfigurationResults { get; set; }
// Overall Metrics
public int TotalIssuesFound { get; set; }
public int OverallRiskScore { get; set; }
public string OverallRiskLevel { get; set; }
public List<string> OverallRecommendations { get; set; } = new List<string>();
public List<string> AnalysisErrors { get; set; } = new List<string>();
// Analysis Metadata
public Dictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
}
}