recoder-security
Version:
Enterprise-grade security and compliance layer for CodeCraft CLI
559 lines • 24.2 kB
JavaScript
"use strict";
/**
* Comprehensive Security Audit Suite
* Orchestrates all security testing and monitoring tools
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecurityAuditor = void 0;
exports.createSecurityAuditor = createSecurityAuditor;
const events_1 = require("events");
const crypto_1 = __importDefault(require("crypto"));
const security_testing_1 = require("./security-testing");
const penetration_testing_1 = require("./penetration-testing");
const code_vulnerability_scanner_1 = require("./code-vulnerability-scanner");
const ai_prompt_sanitizer_1 = require("./ai-prompt-sanitizer");
class SecurityAuditor extends events_1.EventEmitter {
constructor(config) {
super();
this.isRunning = false;
this.config = config;
this.initializeTools();
}
/**
* Initialize security tools based on configuration
*/
initializeTools() {
if (this.config.enabledTests.securityTesting) {
this.testingSuite = new security_testing_1.SecurityTestingSuite();
}
if (this.config.enabledTests.penetrationTesting) {
const penTestConfig = {
target: {
id: crypto_1.default.randomUUID(),
name: this.config.target.name,
baseUrl: this.config.target.baseUrl,
scope: this.config.target.scope,
excludedPaths: ['/health', '/favicon.ico']
},
maxConcurrency: 5,
timeout: 30000,
userAgent: 'Recoder Security Audit Suite',
followRedirects: true,
maxRedirects: 5,
aggressive: false,
skipSlowTests: false,
delayBetweenRequests: 1000,
reportFormat: 'json',
...this.config.penetrationTestConfig
};
this.penetrationTester = new penetration_testing_1.PenetrationTester(penTestConfig);
}
if (this.config.enabledTests.codeScanning && this.config.codebasePath) {
this.codeScanner = new code_vulnerability_scanner_1.CodeVulnerabilityScanner();
}
if (this.config.enabledTests.promptSanitization) {
this.promptSanitizer = new ai_prompt_sanitizer_1.AIPromptSanitizer();
}
}
/**
* Run comprehensive security audit
*/
async runAudit() {
if (this.isRunning) {
throw new Error('Security audit is already running');
}
this.isRunning = true;
const startTime = Date.now();
try {
this.emit('auditStarted', { target: this.config.target, timestamp: new Date() });
// Run all enabled security tests in parallel where possible
const results = await Promise.allSettled([
this.runSecurityTesting(),
this.runPenetrationTesting(),
this.runCodeSecurityScanning(),
this.gatherRouterSecurityMetrics(),
this.analyzePromptSecurity()
]);
// Process results
const [testingResult, penTestResult, codeResult, routerResult, promptResult] = results;
const report = await this.generateComprehensiveReport({
testingReport: testingResult.status === 'fulfilled' ? testingResult.value : undefined,
penetrationReport: penTestResult.status === 'fulfilled' ? penTestResult.value : undefined,
codeSecurityReport: codeResult.status === 'fulfilled' ? codeResult.value : undefined,
routerSecurityReport: routerResult.status === 'fulfilled' ? routerResult.value : undefined,
promptSecurityReport: promptResult.status === 'fulfilled' ? promptResult.value : undefined,
executionTime: Date.now() - startTime
});
this.emit('auditCompleted', report);
return report;
}
catch (error) {
this.emit('auditError', error);
throw error;
}
finally {
this.isRunning = false;
}
}
/**
* Run security testing suite
*/
async runSecurityTesting() {
if (!this.testingSuite)
return undefined;
this.emit('phaseStarted', 'Security Testing');
const report = await this.testingSuite.runAllTests();
this.emit('phaseCompleted', 'Security Testing');
return report;
}
/**
* Run penetration testing
*/
async runPenetrationTesting() {
if (!this.penetrationTester)
return undefined;
this.emit('phaseStarted', 'Penetration Testing');
const report = await this.penetrationTester.startTest();
this.emit('phaseCompleted', 'Penetration Testing');
return report;
}
/**
* Run code security scanning
*/
async runCodeSecurityScanning() {
if (!this.codeScanner || !this.config.codebasePath)
return undefined;
this.emit('phaseStarted', 'Code Security Scanning');
const startTime = Date.now();
const scanResults = await this.codeScanner.scanDirectory(this.config.codebasePath);
const scanDuration = Date.now() - startTime;
const vulnerabilityCount = scanResults.length;
const allVulns = scanResults;
const report = {
scanResults: [{
totalFiles: scanResults.length,
vulnerabilities: scanResults,
securityScore: Math.max(0, 100 - vulnerabilityCount * 10),
summary: {
critical: allVulns.filter(v => v.severity === 'critical').length,
high: allVulns.filter(v => v.severity === 'high').length,
medium: allVulns.filter(v => v.severity === 'medium').length,
low: allVulns.filter(v => v.severity === 'low').length
}
}],
vulnerabilityCount,
criticalIssues: allVulns.filter(v => v.severity === 'critical').length,
highIssues: allVulns.filter(v => v.severity === 'high').length,
mediumIssues: allVulns.filter(v => v.severity === 'medium').length,
lowIssues: allVulns.filter(v => v.severity === 'low').length,
filesScanned: scanResults.length,
scanDuration
};
this.emit('phaseCompleted', 'Code Security Scanning');
return report;
}
/**
* Gather router security metrics
*/
async gatherRouterSecurityMetrics() {
if (!this.routerSecurity)
return undefined;
this.emit('phaseStarted', 'Router Security Analysis');
const metrics = this.routerSecurity.getSecurityMetrics();
const recentEvents = this.routerSecurity.getRecentSecurityEvents(50);
const healthCheck = this.routerSecurity.healthCheck();
const report = {
metrics,
activeThreats: recentEvents.filter(e => e.severity === 'high' || e.severity === 'critical').length,
blockedRequests: metrics.blockedRequests,
securityEvents: recentEvents.length,
averageRiskScore: metrics.averageRiskScore,
systemHealth: healthCheck.status
};
this.emit('phaseCompleted', 'Router Security Analysis');
return report;
}
/**
* Analyze prompt security
*/
async analyzePromptSecurity() {
if (!this.promptSanitizer)
return undefined;
this.emit('phaseStarted', 'Prompt Security Analysis');
// This would analyze recent prompt sanitization data
// For demonstration, we'll return mock data
const report = {
totalPrompts: 1000,
sanitizedPrompts: 950,
blockedPrompts: 25,
highRiskPrompts: 15,
commonThreats: ['prompt injection', 'data extraction', 'code injection'],
sanitizationEffectiveness: 95
};
this.emit('phaseCompleted', 'Prompt Security Analysis');
return report;
}
/**
* Generate comprehensive security report
*/
async generateComprehensiveReport(data) {
// Consolidate findings from all sources
const consolidatedFindings = this.consolidateFindings(data);
// Generate prioritized recommendations
const prioritizedRecommendations = this.generatePrioritizedRecommendations(consolidatedFindings);
// Assess compliance
const complianceAssessment = this.assessCompliance(consolidatedFindings);
// Calculate overall security score
const overallSecurityScore = this.calculateOverallSecurityScore(data, consolidatedFindings);
// Determine risk level
const riskLevel = this.determineRiskLevel(consolidatedFindings, overallSecurityScore);
// Generate executive summary
const executiveSummary = this.generateExecutiveSummary(consolidatedFindings, overallSecurityScore, riskLevel);
// Generate next steps
const nextSteps = this.generateNextSteps(prioritizedRecommendations, riskLevel);
return {
id: crypto_1.default.randomUUID(),
timestamp: new Date(),
target: {
baseUrl: this.config.target.baseUrl,
name: this.config.target.name
},
overallSecurityScore,
riskLevel,
executionTime: data.executionTime,
testingReport: data.testingReport,
penetrationReport: data.penetrationReport,
codeSecurityReport: data.codeSecurityReport,
routerSecurityReport: data.routerSecurityReport,
promptSecurityReport: data.promptSecurityReport,
consolidatedFindings,
prioritizedRecommendations,
complianceAssessment,
executiveSummary,
nextSteps
};
}
/**
* Consolidate findings from all security tools
*/
consolidateFindings(data) {
const findings = [];
let priority = 1;
// Add findings from security testing
if (data.testingReport?.vulnerabilities) {
data.testingReport.vulnerabilities.forEach((vuln) => {
findings.push({
id: vuln.id || crypto_1.default.randomUUID(),
title: vuln.title,
description: vuln.description,
severity: vuln.severity,
category: vuln.type || 'Security Testing',
sources: ['Security Testing Suite'],
affectedComponents: ['Application'],
impact: vuln.impact,
remediation: vuln.remediation,
priority: priority++,
estimatedEffort: this.estimateEffort(vuln.severity),
businessImpact: this.estimateBusinessImpact(vuln.severity)
});
});
}
// Add findings from penetration testing
if (data.penetrationReport?.findings) {
data.penetrationReport.findings.forEach((finding) => {
findings.push({
id: finding.id,
title: finding.title,
description: finding.description,
severity: finding.severity,
category: finding.category,
sources: ['Penetration Testing'],
affectedComponents: finding.affectedUrls || ['Application'],
impact: finding.impact,
remediation: finding.remediation,
priority: priority++,
estimatedEffort: this.estimateEffort(finding.severity),
businessImpact: this.estimateBusinessImpact(finding.severity)
});
});
}
// Add findings from code scanning
if (data.codeSecurityReport?.scanResults) {
data.codeSecurityReport.scanResults.forEach((result) => {
result.vulnerabilities?.forEach((vuln) => {
findings.push({
id: vuln.id || crypto_1.default.randomUUID(),
title: `Code Security: ${vuln.type}`,
description: vuln.description,
severity: vuln.severity,
category: 'Code Security',
sources: ['Code Scanner'],
affectedComponents: [result.filePath],
impact: vuln.impact || 'Code-level security vulnerability',
remediation: vuln.recommendation || 'Review and fix code vulnerability',
priority: priority++,
estimatedEffort: this.estimateEffort(vuln.severity),
businessImpact: this.estimateBusinessImpact(vuln.severity)
});
});
});
}
// Sort by priority (critical first, then by discovery order)
return findings.sort((a, b) => {
const severityOrder = { critical: 4, high: 3, medium: 2, low: 1 };
const aSeverity = severityOrder[a.severity];
const bSeverity = severityOrder[b.severity];
if (aSeverity !== bSeverity) {
return bSeverity - aSeverity;
}
return a.priority - b.priority;
});
}
/**
* Generate prioritized recommendations
*/
generatePrioritizedRecommendations(findings) {
const recommendations = [];
// Group findings by category and severity
const criticalFindings = findings.filter(f => f.severity === 'critical');
const highFindings = findings.filter(f => f.severity === 'high');
const mediumFindings = findings.filter(f => f.severity === 'medium');
const lowFindings = findings.filter(f => f.severity === 'low');
// Immediate actions for critical issues
if (criticalFindings.length > 0) {
recommendations.push({
id: crypto_1.default.randomUUID(),
title: 'Address Critical Security Vulnerabilities',
description: 'Immediately address all critical severity security vulnerabilities',
priority: 'immediate',
effort: 'high',
impact: 'critical',
timeline: 'Within 24 hours',
findings: criticalFindings.map(f => f.id),
actionItems: [
'Form incident response team',
'Assess immediate threat exposure',
'Implement temporary mitigations',
'Apply security patches',
'Verify fixes with testing'
]
});
}
// High priority for high severity issues
if (highFindings.length > 0) {
recommendations.push({
id: crypto_1.default.randomUUID(),
title: 'Remediate High Severity Security Issues',
description: 'Address high severity security vulnerabilities within the next sprint',
priority: 'high',
effort: 'medium',
impact: 'high',
timeline: 'Within 1-2 weeks',
findings: highFindings.map(f => f.id),
actionItems: [
'Prioritize in development backlog',
'Assign security-experienced developers',
'Implement comprehensive fixes',
'Conduct thorough testing',
'Update security documentation'
]
});
}
// Medium priority recommendations
if (mediumFindings.length > 0) {
recommendations.push({
id: crypto_1.default.randomUUID(),
title: 'Improve Security Posture',
description: 'Address medium severity issues and improve overall security posture',
priority: 'medium',
effort: 'medium',
impact: 'medium',
timeline: 'Within 1 month',
findings: mediumFindings.map(f => f.id),
actionItems: [
'Plan security improvements',
'Implement security best practices',
'Enhance monitoring and logging',
'Update security policies',
'Conduct security training'
]
});
}
// Long-term security improvements
recommendations.push({
id: crypto_1.default.randomUUID(),
title: 'Implement Continuous Security Program',
description: 'Establish ongoing security practices and monitoring',
priority: 'medium',
effort: 'high',
impact: 'high',
timeline: 'Ongoing',
findings: [],
actionItems: [
'Implement automated security testing in CI/CD',
'Establish regular security audits',
'Create security incident response procedures',
'Implement security awareness training',
'Deploy continuous monitoring solutions'
]
});
return recommendations;
}
/**
* Assess compliance with various standards
*/
assessCompliance(findings) {
const criticalCount = findings.filter(f => f.severity === 'critical').length;
const highCount = findings.filter(f => f.severity === 'high').length;
const totalFindings = findings.length;
// Calculate base scores
const baseScore = Math.max(0, 100 - (criticalCount * 30) - (highCount * 15) - (totalFindings * 2));
return {
owasp: {
score: Math.max(0, baseScore - (criticalCount * 10)),
status: baseScore >= 80 ? 'compliant' : baseScore >= 60 ? 'partial' : 'non-compliant',
missingControls: criticalCount > 0 ? ['Input Validation', 'Authentication'] : []
},
nist: {
score: baseScore,
status: baseScore >= 85 ? 'compliant' : baseScore >= 70 ? 'partial' : 'non-compliant',
frameworks: ['NIST Cybersecurity Framework']
},
iso27001: {
score: Math.max(0, baseScore - (highCount * 5)),
status: baseScore >= 90 ? 'compliant' : baseScore >= 75 ? 'partial' : 'non-compliant',
gaps: criticalCount > 0 ? ['Security Controls', 'Risk Management'] : []
},
gdpr: {
score: baseScore,
status: baseScore >= 85 ? 'compliant' : baseScore >= 70 ? 'partial' : 'non-compliant',
dataProtectionGaps: findings.some(f => f.category.includes('Data')) ? ['Data Protection'] : []
},
soc2: {
score: Math.max(0, baseScore - (criticalCount * 20)),
status: baseScore >= 90 ? 'compliant' : baseScore >= 75 ? 'partial' : 'non-compliant',
controlGaps: criticalCount > 0 ? ['Security', 'Availability'] : []
}
};
}
/**
* Calculate overall security score
*/
calculateOverallSecurityScore(data, findings) {
let totalScore = 0;
let componentCount = 0;
// Security testing score
if (data.testingReport) {
totalScore += data.testingReport.overallScore || 0;
componentCount++;
}
// Code security score
if (data.codeSecurityReport) {
const codeScore = Math.max(0, 100 - (data.codeSecurityReport.criticalIssues * 30) -
(data.codeSecurityReport.highIssues * 15));
totalScore += codeScore;
componentCount++;
}
// Router security score
if (data.routerSecurityReport) {
const routerScore = 100 - data.routerSecurityReport.averageRiskScore;
totalScore += Math.max(0, routerScore);
componentCount++;
}
// Prompt security score
if (data.promptSecurityReport) {
totalScore += data.promptSecurityReport.sanitizationEffectiveness || 0;
componentCount++;
}
// Calculate weighted average
const baseScore = componentCount > 0 ? totalScore / componentCount : 100;
// Adjust for findings
const criticalPenalty = findings.filter(f => f.severity === 'critical').length * 20;
const highPenalty = findings.filter(f => f.severity === 'high').length * 10;
return Math.max(0, Math.min(100, baseScore - criticalPenalty - highPenalty));
}
/**
* Determine overall risk level
*/
determineRiskLevel(findings, score) {
const criticalCount = findings.filter(f => f.severity === 'critical').length;
const highCount = findings.filter(f => f.severity === 'high').length;
if (criticalCount > 0 || score < 40)
return 'critical';
if (highCount > 2 || score < 60)
return 'high';
if (highCount > 0 || score < 80)
return 'medium';
return 'low';
}
/**
* Generate executive summary
*/
generateExecutiveSummary(findings, score, riskLevel) {
const criticalCount = findings.filter(f => f.severity === 'critical').length;
const highCount = findings.filter(f => f.severity === 'high').length;
const totalCount = findings.length;
if (totalCount === 0) {
return `The comprehensive security audit found no significant security vulnerabilities. ` +
`The application demonstrates strong security practices with an overall security score of ${score}/100.`;
}
return `The comprehensive security audit identified ${totalCount} security findings with an overall ` +
`security score of ${score}/100 and a ${riskLevel} risk level. Critical issues: ${criticalCount}, ` +
`High severity issues: ${highCount}. ${criticalCount > 0 ? 'Immediate action is required for critical issues. ' : ''}` +
`Recommended to address high-severity issues within the next development cycle.`;
}
/**
* Generate next steps
*/
generateNextSteps(recommendations, riskLevel) {
const steps = [];
if (riskLevel === 'critical') {
steps.push('Form immediate incident response team');
steps.push('Assess and contain critical security threats');
steps.push('Implement emergency security patches');
}
steps.push('Review and prioritize security recommendations');
steps.push('Assign security tasks to development team');
steps.push('Implement comprehensive security testing in CI/CD');
steps.push('Schedule regular security audits');
steps.push('Establish security monitoring and alerting');
return steps;
}
/**
* Helper methods
*/
estimateEffort(severity) {
switch (severity) {
case 'critical': return 'high';
case 'high': return 'medium';
case 'medium': return 'medium';
case 'low': return 'low';
default: return 'medium';
}
}
estimateBusinessImpact(severity) {
switch (severity) {
case 'critical': return 'critical';
case 'high': return 'high';
case 'medium': return 'medium';
case 'low': return 'low';
default: return 'medium';
}
}
/**
* Get audit status
*/
getStatus() {
return { isRunning: this.isRunning };
}
}
exports.SecurityAuditor = SecurityAuditor;
// Export factory function
function createSecurityAuditor(config) {
return new SecurityAuditor(config);
}
exports.default = SecurityAuditor;
//# sourceMappingURL=security-audit.js.map