473 lines
20 KiB
C#
Executable File
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>();
|
|
}
|
|
} |