UNPKG

vibesec

Version:

Security scanner for AI-generated code - detects vulnerabilities in vibe-coded projects

229 lines 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StakeholderReporter = void 0; const types_1 = require("../scanner/core/types"); const security_score_1 = require("../lib/utils/security-score"); class StakeholderReporter { generate(result) { const securityScore = (0, security_score_1.calculateSecurityScore)(result); const benchmark = (0, security_score_1.getBenchmarkComparison)(securityScore.score, result.scan.filesScanned); const lines = []; lines.push('═'.repeat(70)); lines.push(' SECURITY ASSESSMENT REPORT'); lines.push('═'.repeat(70)); lines.push(''); lines.push('EXECUTIVE SUMMARY'); lines.push('─'.repeat(70)); lines.push(''); lines.push(`Project: ${this.getProjectName(result.scan.path)}`); lines.push(`Assessment Date: ${new Date(result.scan.timestamp).toLocaleDateString()}`); lines.push(`Files Analyzed: ${result.scan.filesScanned}`); lines.push(`Analysis Duration: ${result.scan.duration.toFixed(1)} seconds`); lines.push(''); lines.push('SECURITY SCORE'); lines.push('─'.repeat(70)); lines.push(''); lines.push(`Overall Score: ${securityScore.score}/100 (${securityScore.grade})`); lines.push(`Security Rating: ${securityScore.rating}`); lines.push(''); lines.push(`Benchmark: ${benchmark}`); lines.push(''); lines.push('RISK ASSESSMENT'); lines.push('─'.repeat(70)); lines.push(''); lines.push(this.formatRiskAssessment(result, securityScore)); lines.push(''); lines.push('FINDINGS SUMMARY'); lines.push('─'.repeat(70)); lines.push(''); const { bySeverity } = result.summary; if (result.summary.total === 0) { lines.push('✓ No security vulnerabilities detected'); lines.push(''); lines.push('The codebase follows security best practices and no'); lines.push('immediate security concerns were identified.'); lines.push(''); } else { lines.push(`Total Security Issues: ${result.summary.total}`); lines.push(''); lines.push('Breakdown by Severity:'); lines.push(` • Critical (Immediate Action): ${bySeverity.critical}`); lines.push(` • High (This Week): ${bySeverity.high}`); lines.push(` • Medium (This Month): ${bySeverity.medium}`); lines.push(` • Low (Best Practice): ${bySeverity.low}`); lines.push(''); if (bySeverity.critical > 0 || bySeverity.high > 0) { lines.push('KEY ISSUES REQUIRING ATTENTION'); lines.push('─'.repeat(70)); lines.push(''); lines.push(this.formatKeyIssues(result)); lines.push(''); } } lines.push('RECOMMENDATIONS'); lines.push('─'.repeat(70)); lines.push(''); lines.push(securityScore.recommendation); lines.push(''); if (result.summary.total > 0) { lines.push('Recommended Actions:'); lines.push(this.formatRecommendedActions(result)); lines.push(''); } lines.push('BUSINESS IMPACT'); lines.push('─'.repeat(70)); lines.push(''); lines.push(this.formatBusinessImpact(result, securityScore)); lines.push(''); lines.push('═'.repeat(70)); lines.push('Generated by VibeSec Security Scanner'); lines.push(`Report Date: ${new Date().toISOString()}`); lines.push('═'.repeat(70)); return lines.join('\n'); } getProjectName(path) { const parts = path.split('/'); return parts[parts.length - 1] || 'Current Project'; } formatRiskAssessment(result, securityScore) { const { bySeverity } = result.summary; const lines = []; if (securityScore.score >= 90) { lines.push('Risk Level: LOW'); lines.push(''); lines.push('The codebase demonstrates strong security practices with'); lines.push('minimal vulnerabilities. Continue monitoring and maintaining'); lines.push('current security standards.'); } else if (securityScore.score >= 70) { lines.push('Risk Level: MODERATE'); lines.push(''); lines.push('The codebase has some security concerns that should be'); lines.push('addressed. Prioritize fixing high-severity issues to reduce'); lines.push('potential security risks.'); } else { lines.push('Risk Level: HIGH'); lines.push(''); lines.push('The codebase contains significant security vulnerabilities'); lines.push('that require immediate attention. Failure to address these'); lines.push('issues may result in data breaches or security incidents.'); } if (bySeverity.critical > 0) { lines.push(''); lines.push(`⚠️ CRITICAL: ${bySeverity.critical} critical issue${bySeverity.critical > 1 ? 's' : ''} require immediate remediation.`); } return lines.join('\n'); } formatKeyIssues(result) { const keyFindings = result.findings .filter((f) => f.severity === types_1.Severity.CRITICAL || f.severity === types_1.Severity.HIGH) .slice(0, 5); const lines = []; keyFindings.forEach((finding, idx) => { lines.push(`${idx + 1}. ${finding.title}`); lines.push(` Severity: ${finding.severity.toUpperCase()}`); lines.push(` Location: ${finding.location.file}`); lines.push(` Impact: ${this.getBusinessImpact(finding)}`); lines.push(''); }); if (result.findings.length > 5) { lines.push(`... and ${result.findings.length - 5} additional issue${result.findings.length - 5 > 1 ? 's' : ''}`); } return lines.join('\n'); } formatRecommendedActions(result) { const { bySeverity } = result.summary; const lines = []; let actionNumber = 1; if (bySeverity.critical > 0) { lines.push(` ${actionNumber}. Fix ${bySeverity.critical} critical issue${bySeverity.critical > 1 ? 's' : ''} within 24 hours`); actionNumber++; } if (bySeverity.high > 0) { lines.push(` ${actionNumber}. Address ${bySeverity.high} high-severity issue${bySeverity.high > 1 ? 's' : ''} within 7 days`); actionNumber++; } if (bySeverity.medium > 0) { lines.push(` ${actionNumber}. Schedule remediation of ${bySeverity.medium} medium-severity issue${bySeverity.medium > 1 ? 's' : ''}`); actionNumber++; } lines.push(` ${actionNumber}. Conduct follow-up scan after remediation to verify fixes`); actionNumber++; lines.push(` ${actionNumber}. Implement regular security scanning in development workflow`); return lines.join('\n'); } formatBusinessImpact(result, securityScore) { const { bySeverity } = result.summary; const lines = []; if (result.summary.total === 0) { lines.push('Positive Impact:'); lines.push(' • Low risk of security incidents'); lines.push(' • Reduced liability and compliance concerns'); lines.push(' • Enhanced customer trust and brand reputation'); lines.push(' • Lower potential costs from security breaches'); return lines.join('\n'); } lines.push('Potential Risks if Unaddressed:'); if (bySeverity.critical > 0) { lines.push(' • HIGH RISK: Potential for immediate security breach'); lines.push(' • Financial exposure from data theft or service disruption'); lines.push(' • Regulatory compliance violations and fines'); lines.push(' • Reputational damage and loss of customer trust'); } else if (bySeverity.high > 0) { lines.push(' • MODERATE RISK: Vulnerabilities exploitable by attackers'); lines.push(' • Potential for data exposure or unauthorized access'); lines.push(' • Compliance concerns depending on industry'); lines.push(' • Increased attack surface'); } else { lines.push(' • LOW RISK: Minor security improvements recommended'); lines.push(' • Adherence to security best practices'); lines.push(' • Reduced future technical debt'); } lines.push(''); lines.push('Cost of Remediation:'); const estimatedHours = this.estimateRemediationHours(result); lines.push(` Estimated engineering time: ${estimatedHours.min}-${estimatedHours.max} hours`); return lines.join('\n'); } getBusinessImpact(finding) { const impacts = { secrets: 'Unauthorized access to systems and services', injection: 'Database compromise and data theft', 'sql-injection': 'Complete database access and data manipulation', xss: 'User account compromise and phishing attacks', auth: 'Unauthorized access to protected resources', 'command-injection': 'Complete system takeover', default: 'Security vulnerability exploitation', }; const categoryKey = finding.category.toLowerCase(); const ruleKey = finding.rule.toLowerCase(); return impacts[ruleKey] || impacts[categoryKey] || impacts['default']; } estimateRemediationHours(result) { const { bySeverity } = result.summary; const timePerIssue = { critical: { min: 0.5, max: 2 }, high: { min: 0.3, max: 1 }, medium: { min: 0.2, max: 0.5 }, low: { min: 0.1, max: 0.3 }, }; const minHours = bySeverity.critical * timePerIssue.critical.min + bySeverity.high * timePerIssue.high.min + bySeverity.medium * timePerIssue.medium.min + bySeverity.low * timePerIssue.low.min; const maxHours = bySeverity.critical * timePerIssue.critical.max + bySeverity.high * timePerIssue.high.max + bySeverity.medium * timePerIssue.medium.max + bySeverity.low * timePerIssue.low.max; return { min: Math.ceil(minHours), max: Math.ceil(maxHours), }; } } exports.StakeholderReporter = StakeholderReporter; //# sourceMappingURL=stakeholder.js.map