@nahisaho/musubix-security 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -0
- package/bin/musubix-security-mcp.js +12 -0
- package/bin/musubix-security.js +12 -0
- package/dist/analysis/dependency-auditor.d.ts +30 -0
- package/dist/analysis/dependency-auditor.d.ts.map +1 -0
- package/dist/analysis/dependency-auditor.js +325 -0
- package/dist/analysis/dependency-auditor.js.map +1 -0
- package/dist/analysis/index.d.ts +9 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +9 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/secret-detector.d.ts +44 -0
- package/dist/analysis/secret-detector.d.ts.map +1 -0
- package/dist/analysis/secret-detector.js +465 -0
- package/dist/analysis/secret-detector.js.map +1 -0
- package/dist/analysis/taint-analyzer.d.ts +62 -0
- package/dist/analysis/taint-analyzer.d.ts.map +1 -0
- package/dist/analysis/taint-analyzer.js +519 -0
- package/dist/analysis/taint-analyzer.js.map +1 -0
- package/dist/analysis/vulnerability-scanner.d.ts +58 -0
- package/dist/analysis/vulnerability-scanner.d.ts.map +1 -0
- package/dist/analysis/vulnerability-scanner.js +417 -0
- package/dist/analysis/vulnerability-scanner.js.map +1 -0
- package/dist/cli/commands.d.ts +15 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +405 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +6 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/ast-parser.d.ts +87 -0
- package/dist/infrastructure/ast-parser.d.ts.map +1 -0
- package/dist/infrastructure/ast-parser.js +273 -0
- package/dist/infrastructure/ast-parser.js.map +1 -0
- package/dist/infrastructure/cache.d.ts +100 -0
- package/dist/infrastructure/cache.d.ts.map +1 -0
- package/dist/infrastructure/cache.js +288 -0
- package/dist/infrastructure/cache.js.map +1 -0
- package/dist/infrastructure/config-loader.d.ts +35 -0
- package/dist/infrastructure/config-loader.d.ts.map +1 -0
- package/dist/infrastructure/config-loader.js +358 -0
- package/dist/infrastructure/config-loader.js.map +1 -0
- package/dist/infrastructure/file-scanner.d.ts +94 -0
- package/dist/infrastructure/file-scanner.d.ts.map +1 -0
- package/dist/infrastructure/file-scanner.js +189 -0
- package/dist/infrastructure/file-scanner.js.map +1 -0
- package/dist/infrastructure/index.d.ts +9 -0
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/index.js +9 -0
- package/dist/infrastructure/index.js.map +1 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +7 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +34 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +88 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +88 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +443 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/services/fix-generator.d.ts +56 -0
- package/dist/services/fix-generator.d.ts.map +1 -0
- package/dist/services/fix-generator.js +346 -0
- package/dist/services/fix-generator.js.map +1 -0
- package/dist/services/fix-verifier.d.ts +62 -0
- package/dist/services/fix-verifier.d.ts.map +1 -0
- package/dist/services/fix-verifier.js +224 -0
- package/dist/services/fix-verifier.js.map +1 -0
- package/dist/services/index.d.ts +9 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +13 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/report-generator.d.ts +87 -0
- package/dist/services/report-generator.d.ts.map +1 -0
- package/dist/services/report-generator.js +463 -0
- package/dist/services/report-generator.js.map +1 -0
- package/dist/services/security-service.d.ts +151 -0
- package/dist/services/security-service.d.ts.map +1 -0
- package/dist/services/security-service.js +279 -0
- package/dist/services/security-service.js.map +1 -0
- package/dist/types/config.d.ts +188 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +89 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/dependency.d.ts +266 -0
- package/dist/types/dependency.d.ts.map +1 -0
- package/dist/types/dependency.js +7 -0
- package/dist/types/dependency.js.map +1 -0
- package/dist/types/fix.d.ts +213 -0
- package/dist/types/fix.d.ts.map +1 -0
- package/dist/types/fix.js +7 -0
- package/dist/types/fix.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/secret.d.ts +151 -0
- package/dist/types/secret.d.ts.map +1 -0
- package/dist/types/secret.js +91 -0
- package/dist/types/secret.js.map +1 -0
- package/dist/types/taint.d.ts +182 -0
- package/dist/types/taint.d.ts.map +1 -0
- package/dist/types/taint.js +24 -0
- package/dist/types/taint.js.map +1 -0
- package/dist/types/vulnerability.d.ts +136 -0
- package/dist/types/vulnerability.d.ts.map +1 -0
- package/dist/types/vulnerability.js +7 -0
- package/dist/types/vulnerability.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Services module entry point
|
|
3
|
+
* @module @nahisaho/musubix-security/services
|
|
4
|
+
*/
|
|
5
|
+
// Fix generator
|
|
6
|
+
export { FixGenerator, createFixGenerator, } from './fix-generator.js';
|
|
7
|
+
// Fix verifier
|
|
8
|
+
export { FixVerifier, createFixVerifier, } from './fix-verifier.js';
|
|
9
|
+
// Report generator
|
|
10
|
+
export { ReportGenerator, createReportGenerator, } from './report-generator.js';
|
|
11
|
+
// Security service (main facade)
|
|
12
|
+
export { SecurityService, createSecurityService, scanForVulnerabilities, runSecurityScan, } from './security-service.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,gBAAgB;AAChB,OAAO,EACL,YAAY,EACZ,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,eAAe;AACf,OAAO,EACL,WAAW,EACX,iBAAiB,GAElB,MAAM,mBAAmB,CAAC;AAE3B,mBAAmB;AACnB,OAAO,EACL,eAAe,EACf,qBAAqB,GAItB,MAAM,uBAAuB,CAAC;AAE/B,iCAAiC;AACjC,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,GAGhB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Report generator service - generates security reports in multiple formats
|
|
3
|
+
* @module @nahisaho/musubix-security/services/report-generator
|
|
4
|
+
* @trace REQ-SEC-REP-001
|
|
5
|
+
*/
|
|
6
|
+
import type { ScanResult, Fix, AuditResult, TaintResult, SecretScanResult, ReportConfig, ReportFormat } from '../types/index.js';
|
|
7
|
+
export type { ReportFormat };
|
|
8
|
+
/**
|
|
9
|
+
* Combined scan results for report generation
|
|
10
|
+
*/
|
|
11
|
+
export interface CombinedResults {
|
|
12
|
+
vulnerabilities: ScanResult;
|
|
13
|
+
dependencies?: AuditResult;
|
|
14
|
+
taint?: TaintResult;
|
|
15
|
+
secrets?: SecretScanResult;
|
|
16
|
+
fixes?: Fix[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Report metadata
|
|
20
|
+
*/
|
|
21
|
+
export interface ReportMetadata {
|
|
22
|
+
title: string;
|
|
23
|
+
project?: string;
|
|
24
|
+
scanTime: Date;
|
|
25
|
+
duration: number;
|
|
26
|
+
targetPath: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Report generator class
|
|
30
|
+
*/
|
|
31
|
+
export declare class ReportGenerator {
|
|
32
|
+
private config;
|
|
33
|
+
constructor(config?: Partial<ReportConfig>);
|
|
34
|
+
/**
|
|
35
|
+
* Generate report in specified format
|
|
36
|
+
*/
|
|
37
|
+
generate(results: CombinedResults, metadata: ReportMetadata, format?: ReportFormat): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Generate and save report to file
|
|
40
|
+
*/
|
|
41
|
+
generateToFile(results: CombinedResults, metadata: ReportMetadata, outputPath: string, format?: ReportFormat): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Generate all configured formats
|
|
44
|
+
*/
|
|
45
|
+
generateAll(results: CombinedResults, metadata: ReportMetadata): Promise<Map<ReportFormat, string>>;
|
|
46
|
+
/**
|
|
47
|
+
* Generate JSON report
|
|
48
|
+
*/
|
|
49
|
+
private generateJSON;
|
|
50
|
+
/**
|
|
51
|
+
* Generate SARIF report
|
|
52
|
+
*/
|
|
53
|
+
private generateSARIF;
|
|
54
|
+
/**
|
|
55
|
+
* Generate Markdown report
|
|
56
|
+
*/
|
|
57
|
+
private generateMarkdown;
|
|
58
|
+
/**
|
|
59
|
+
* Generate HTML report
|
|
60
|
+
*/
|
|
61
|
+
private generateHTML;
|
|
62
|
+
/**
|
|
63
|
+
* Generate summary statistics
|
|
64
|
+
*/
|
|
65
|
+
private generateSummary;
|
|
66
|
+
/**
|
|
67
|
+
* Format vulnerabilities based on config
|
|
68
|
+
*/
|
|
69
|
+
private formatVulnerabilities;
|
|
70
|
+
/**
|
|
71
|
+
* Group vulnerabilities by severity
|
|
72
|
+
*/
|
|
73
|
+
private groupBySeverity;
|
|
74
|
+
/**
|
|
75
|
+
* Convert severity to SARIF level
|
|
76
|
+
*/
|
|
77
|
+
private severityToSARIFLevel;
|
|
78
|
+
/**
|
|
79
|
+
* Escape HTML entities
|
|
80
|
+
*/
|
|
81
|
+
private escapeHtml;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a report generator
|
|
85
|
+
*/
|
|
86
|
+
export declare function createReportGenerator(config?: Partial<ReportConfig>): ReportGenerator;
|
|
87
|
+
//# sourceMappingURL=report-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-generator.d.ts","sourceRoot":"","sources":["../../src/services/report-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAEV,UAAU,EAEV,GAAG,EACH,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,UAAU,CAAC;IAC5B,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmDD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAiG;gBAEnG,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAU9C;;OAEG;IACG,QAAQ,CACZ,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,cAAc,EACxB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC;IAiBlB;;OAEG;IACG,cAAc,CAClB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC;IAalB;;OAEG;IACG,WAAW,CACf,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAYrC;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;IACH,OAAO,CAAC,aAAa;IA0DrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyFxB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6JpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAyBvB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;IACH,OAAO,CAAC,UAAU;CAQnB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,eAAe,CAErF"}
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Report generator service - generates security reports in multiple formats
|
|
3
|
+
* @module @nahisaho/musubix-security/services/report-generator
|
|
4
|
+
* @trace REQ-SEC-REP-001
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs/promises';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
/**
|
|
9
|
+
* Report generator class
|
|
10
|
+
*/
|
|
11
|
+
export class ReportGenerator {
|
|
12
|
+
config;
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
this.config = {
|
|
15
|
+
format: Array.isArray(config.format) ? config.format : config.format ? [config.format] : ['json'],
|
|
16
|
+
includeCode: config.includeCode ?? config.includeCodeSnippets ?? true,
|
|
17
|
+
includeFixes: config.includeFixes ?? true,
|
|
18
|
+
groupBy: config.groupBy ?? 'severity',
|
|
19
|
+
sortBy: config.sortBy ?? 'severity',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Generate report in specified format
|
|
24
|
+
*/
|
|
25
|
+
async generate(results, metadata, format) {
|
|
26
|
+
const reportFormat = format ?? this.config.format[0];
|
|
27
|
+
switch (reportFormat) {
|
|
28
|
+
case 'json':
|
|
29
|
+
return this.generateJSON(results, metadata);
|
|
30
|
+
case 'sarif':
|
|
31
|
+
return this.generateSARIF(results, metadata);
|
|
32
|
+
case 'markdown':
|
|
33
|
+
return this.generateMarkdown(results, metadata);
|
|
34
|
+
case 'html':
|
|
35
|
+
return this.generateHTML(results, metadata);
|
|
36
|
+
default:
|
|
37
|
+
throw new Error(`Unsupported report format: ${reportFormat}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Generate and save report to file
|
|
42
|
+
*/
|
|
43
|
+
async generateToFile(results, metadata, outputPath, format) {
|
|
44
|
+
const content = await this.generate(results, metadata, format);
|
|
45
|
+
// Ensure directory exists
|
|
46
|
+
const dir = path.dirname(outputPath);
|
|
47
|
+
await fs.mkdir(dir, { recursive: true });
|
|
48
|
+
// Write file
|
|
49
|
+
await fs.writeFile(outputPath, content, 'utf-8');
|
|
50
|
+
return outputPath;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Generate all configured formats
|
|
54
|
+
*/
|
|
55
|
+
async generateAll(results, metadata) {
|
|
56
|
+
const reports = new Map();
|
|
57
|
+
const formats = Array.isArray(this.config.format) ? this.config.format : [this.config.format];
|
|
58
|
+
for (const format of formats) {
|
|
59
|
+
const content = await this.generate(results, metadata, format);
|
|
60
|
+
reports.set(format, content);
|
|
61
|
+
}
|
|
62
|
+
return reports;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate JSON report
|
|
66
|
+
*/
|
|
67
|
+
generateJSON(results, metadata) {
|
|
68
|
+
const report = {
|
|
69
|
+
...metadata,
|
|
70
|
+
scanTime: metadata.scanTime.toISOString(),
|
|
71
|
+
summary: this.generateSummary(results),
|
|
72
|
+
vulnerabilities: this.formatVulnerabilities(results.vulnerabilities.vulnerabilities),
|
|
73
|
+
dependencies: results.dependencies,
|
|
74
|
+
taint: results.taint,
|
|
75
|
+
secrets: results.secrets ? {
|
|
76
|
+
...results.secrets,
|
|
77
|
+
secrets: results.secrets.secrets.map(s => ({
|
|
78
|
+
...s,
|
|
79
|
+
value: s.maskedValue, // Only include masked value
|
|
80
|
+
})),
|
|
81
|
+
} : undefined,
|
|
82
|
+
fixes: this.config.includeFixes ? results.fixes : undefined,
|
|
83
|
+
};
|
|
84
|
+
return JSON.stringify(report, null, 2);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generate SARIF report
|
|
88
|
+
*/
|
|
89
|
+
generateSARIF(results, _metadata) {
|
|
90
|
+
const vulnerabilities = results.vulnerabilities.vulnerabilities;
|
|
91
|
+
// Create rules from unique vulnerability types
|
|
92
|
+
const ruleMap = new Map();
|
|
93
|
+
for (const vuln of vulnerabilities) {
|
|
94
|
+
if (!ruleMap.has(vuln.ruleId)) {
|
|
95
|
+
const cweId = vuln.cwes[0];
|
|
96
|
+
ruleMap.set(vuln.ruleId, {
|
|
97
|
+
id: vuln.ruleId,
|
|
98
|
+
name: vuln.type,
|
|
99
|
+
shortDescription: { text: vuln.type },
|
|
100
|
+
fullDescription: { text: vuln.description },
|
|
101
|
+
helpUri: cweId ? `https://cwe.mitre.org/data/definitions/${cweId.replace('CWE-', '')}.html` : undefined,
|
|
102
|
+
defaultConfiguration: {
|
|
103
|
+
level: this.severityToSARIFLevel(vuln.severity),
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Create results
|
|
109
|
+
const sarifResults = vulnerabilities.map((vuln) => ({
|
|
110
|
+
ruleId: vuln.ruleId,
|
|
111
|
+
level: this.severityToSARIFLevel(vuln.severity),
|
|
112
|
+
message: { text: vuln.description },
|
|
113
|
+
locations: [{
|
|
114
|
+
physicalLocation: {
|
|
115
|
+
artifactLocation: { uri: vuln.location.file },
|
|
116
|
+
region: {
|
|
117
|
+
startLine: vuln.location.startLine,
|
|
118
|
+
startColumn: vuln.location.startColumn,
|
|
119
|
+
endLine: vuln.location.endLine,
|
|
120
|
+
endColumn: vuln.location.endColumn,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
}],
|
|
124
|
+
}));
|
|
125
|
+
const sarifReport = {
|
|
126
|
+
$schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json',
|
|
127
|
+
version: '2.1.0',
|
|
128
|
+
runs: [{
|
|
129
|
+
tool: {
|
|
130
|
+
driver: {
|
|
131
|
+
name: 'musubix-security',
|
|
132
|
+
version: '1.8.0',
|
|
133
|
+
informationUri: 'https://github.com/nahisaho/musubix',
|
|
134
|
+
rules: Array.from(ruleMap.values()),
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
results: sarifResults,
|
|
138
|
+
}],
|
|
139
|
+
};
|
|
140
|
+
return JSON.stringify(sarifReport, null, 2);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Generate Markdown report
|
|
144
|
+
*/
|
|
145
|
+
generateMarkdown(results, metadata) {
|
|
146
|
+
const summary = this.generateSummary(results);
|
|
147
|
+
const vulnerabilities = this.formatVulnerabilities(results.vulnerabilities.vulnerabilities);
|
|
148
|
+
let md = `# Security Scan Report
|
|
149
|
+
|
|
150
|
+
## Summary
|
|
151
|
+
|
|
152
|
+
- **Project**: ${metadata.project ?? 'N/A'}
|
|
153
|
+
- **Target**: ${metadata.targetPath}
|
|
154
|
+
- **Scan Time**: ${metadata.scanTime.toISOString()}
|
|
155
|
+
- **Duration**: ${metadata.duration}ms
|
|
156
|
+
|
|
157
|
+
### Findings Overview
|
|
158
|
+
|
|
159
|
+
| Severity | Count |
|
|
160
|
+
|----------|-------|
|
|
161
|
+
| Critical | ${summary.critical} |
|
|
162
|
+
| High | ${summary.high} |
|
|
163
|
+
| Medium | ${summary.medium} |
|
|
164
|
+
| Low | ${summary.low} |
|
|
165
|
+
| Info | ${summary.info} |
|
|
166
|
+
| **Total** | **${summary.total}** |
|
|
167
|
+
|
|
168
|
+
`;
|
|
169
|
+
// Group vulnerabilities by severity
|
|
170
|
+
const grouped = this.groupBySeverity(vulnerabilities);
|
|
171
|
+
for (const severity of ['critical', 'high', 'medium', 'low', 'info']) {
|
|
172
|
+
const vulns = grouped.get(severity) || [];
|
|
173
|
+
if (vulns.length === 0)
|
|
174
|
+
continue;
|
|
175
|
+
md += `## ${severity.toUpperCase()} Severity (${vulns.length})\n\n`;
|
|
176
|
+
for (const vuln of vulns) {
|
|
177
|
+
md += `### ${vuln.type}\n\n`;
|
|
178
|
+
md += `- **Rule**: ${vuln.ruleId}\n`;
|
|
179
|
+
md += `- **File**: ${vuln.location.file}:${vuln.location.startLine}\n`;
|
|
180
|
+
md += `- **CWE**: ${vuln.cwes[0] ?? 'N/A'}\n`;
|
|
181
|
+
md += `- **OWASP**: ${vuln.owasp?.[0] ?? 'N/A'}\n\n`;
|
|
182
|
+
md += `${vuln.description}\n\n`;
|
|
183
|
+
if (this.config.includeCode && vuln.codeSnippet) {
|
|
184
|
+
md += '```\n' + vuln.codeSnippet + '\n```\n\n';
|
|
185
|
+
}
|
|
186
|
+
if (vuln.recommendation) {
|
|
187
|
+
md += `**Remediation**: ${vuln.recommendation}\n\n`;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Dependencies section
|
|
192
|
+
if (results.dependencies) {
|
|
193
|
+
md += `## Dependency Audit\n\n`;
|
|
194
|
+
md += `- **Vulnerabilities Found**: ${results.dependencies.vulnerableDependencies.length}\n`;
|
|
195
|
+
md += `- **Audit Duration**: ${results.dependencies.duration}ms\n\n`;
|
|
196
|
+
if (results.dependencies.vulnerableDependencies.length > 0) {
|
|
197
|
+
md += `| Package | Version | Severity | Title |\n`;
|
|
198
|
+
md += `|---------|---------|----------|-------|\n`;
|
|
199
|
+
for (const dep of results.dependencies.vulnerableDependencies) {
|
|
200
|
+
md += `| ${dep.name} | ${dep.installedVersion} | ${dep.highestSeverity} | ${dep.vulnerabilities[0]?.title ?? 'N/A'} |\n`;
|
|
201
|
+
}
|
|
202
|
+
md += '\n';
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Secrets section
|
|
206
|
+
if (results.secrets && results.secrets.summary.total > 0) {
|
|
207
|
+
md += `## Secrets Detected\n\n`;
|
|
208
|
+
md += `⚠️ **${results.secrets.summary.total} potential secrets found**\n\n`;
|
|
209
|
+
for (const secret of results.secrets.secrets) {
|
|
210
|
+
md += `- **${secret.type}** in ${secret.location.file}:${secret.location.startLine}\n`;
|
|
211
|
+
}
|
|
212
|
+
md += '\n';
|
|
213
|
+
}
|
|
214
|
+
// Taint analysis section
|
|
215
|
+
if (results.taint && results.taint.unsafePaths.length > 0) {
|
|
216
|
+
md += `## Taint Analysis\n\n`;
|
|
217
|
+
md += `- **Tainted Paths**: ${results.taint.unsafePaths.length}\n\n`;
|
|
218
|
+
}
|
|
219
|
+
return md;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Generate HTML report
|
|
223
|
+
*/
|
|
224
|
+
generateHTML(results, metadata) {
|
|
225
|
+
const summary = this.generateSummary(results);
|
|
226
|
+
const vulnerabilities = this.formatVulnerabilities(results.vulnerabilities.vulnerabilities);
|
|
227
|
+
return `<!DOCTYPE html>
|
|
228
|
+
<html lang="en">
|
|
229
|
+
<head>
|
|
230
|
+
<meta charset="UTF-8">
|
|
231
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
232
|
+
<title>Security Scan Report - ${metadata.project ?? metadata.targetPath}</title>
|
|
233
|
+
<style>
|
|
234
|
+
:root {
|
|
235
|
+
--critical: #d63031;
|
|
236
|
+
--high: #e17055;
|
|
237
|
+
--medium: #fdcb6e;
|
|
238
|
+
--low: #00cec9;
|
|
239
|
+
--info: #74b9ff;
|
|
240
|
+
--bg: #f5f6fa;
|
|
241
|
+
--card: #ffffff;
|
|
242
|
+
--text: #2d3436;
|
|
243
|
+
}
|
|
244
|
+
body {
|
|
245
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
246
|
+
background: var(--bg);
|
|
247
|
+
color: var(--text);
|
|
248
|
+
margin: 0;
|
|
249
|
+
padding: 20px;
|
|
250
|
+
}
|
|
251
|
+
.container {
|
|
252
|
+
max-width: 1200px;
|
|
253
|
+
margin: 0 auto;
|
|
254
|
+
}
|
|
255
|
+
h1 { color: var(--text); }
|
|
256
|
+
.card {
|
|
257
|
+
background: var(--card);
|
|
258
|
+
border-radius: 8px;
|
|
259
|
+
padding: 20px;
|
|
260
|
+
margin-bottom: 20px;
|
|
261
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
262
|
+
}
|
|
263
|
+
.summary-grid {
|
|
264
|
+
display: grid;
|
|
265
|
+
grid-template-columns: repeat(5, 1fr);
|
|
266
|
+
gap: 10px;
|
|
267
|
+
margin-bottom: 20px;
|
|
268
|
+
}
|
|
269
|
+
.summary-item {
|
|
270
|
+
text-align: center;
|
|
271
|
+
padding: 15px;
|
|
272
|
+
border-radius: 8px;
|
|
273
|
+
color: white;
|
|
274
|
+
}
|
|
275
|
+
.summary-item.critical { background: var(--critical); }
|
|
276
|
+
.summary-item.high { background: var(--high); }
|
|
277
|
+
.summary-item.medium { background: var(--medium); color: var(--text); }
|
|
278
|
+
.summary-item.low { background: var(--low); }
|
|
279
|
+
.summary-item.info { background: var(--info); }
|
|
280
|
+
.summary-item .count { font-size: 2em; font-weight: bold; }
|
|
281
|
+
.summary-item .label { font-size: 0.9em; text-transform: uppercase; }
|
|
282
|
+
.vuln {
|
|
283
|
+
border-left: 4px solid;
|
|
284
|
+
padding-left: 15px;
|
|
285
|
+
margin-bottom: 15px;
|
|
286
|
+
}
|
|
287
|
+
.vuln.critical { border-color: var(--critical); }
|
|
288
|
+
.vuln.high { border-color: var(--high); }
|
|
289
|
+
.vuln.medium { border-color: var(--medium); }
|
|
290
|
+
.vuln.low { border-color: var(--low); }
|
|
291
|
+
.vuln.info { border-color: var(--info); }
|
|
292
|
+
.vuln-title {
|
|
293
|
+
font-weight: bold;
|
|
294
|
+
font-size: 1.1em;
|
|
295
|
+
}
|
|
296
|
+
.vuln-meta {
|
|
297
|
+
color: #636e72;
|
|
298
|
+
font-size: 0.9em;
|
|
299
|
+
margin: 5px 0;
|
|
300
|
+
}
|
|
301
|
+
pre {
|
|
302
|
+
background: #2d3436;
|
|
303
|
+
color: #dfe6e9;
|
|
304
|
+
padding: 15px;
|
|
305
|
+
border-radius: 4px;
|
|
306
|
+
overflow-x: auto;
|
|
307
|
+
}
|
|
308
|
+
.badge {
|
|
309
|
+
display: inline-block;
|
|
310
|
+
padding: 2px 8px;
|
|
311
|
+
border-radius: 4px;
|
|
312
|
+
font-size: 0.8em;
|
|
313
|
+
font-weight: bold;
|
|
314
|
+
}
|
|
315
|
+
.badge.critical { background: var(--critical); color: white; }
|
|
316
|
+
.badge.high { background: var(--high); color: white; }
|
|
317
|
+
.badge.medium { background: var(--medium); color: var(--text); }
|
|
318
|
+
.badge.low { background: var(--low); color: white; }
|
|
319
|
+
.badge.info { background: var(--info); color: white; }
|
|
320
|
+
</style>
|
|
321
|
+
</head>
|
|
322
|
+
<body>
|
|
323
|
+
<div class="container">
|
|
324
|
+
<h1>🔒 Security Scan Report</h1>
|
|
325
|
+
|
|
326
|
+
<div class="card">
|
|
327
|
+
<h2>Summary</h2>
|
|
328
|
+
<p><strong>Target:</strong> ${this.escapeHtml(metadata.targetPath)}</p>
|
|
329
|
+
<p><strong>Scan Time:</strong> ${metadata.scanTime.toISOString()}</p>
|
|
330
|
+
<p><strong>Duration:</strong> ${metadata.duration}ms</p>
|
|
331
|
+
|
|
332
|
+
<div class="summary-grid">
|
|
333
|
+
<div class="summary-item critical">
|
|
334
|
+
<div class="count">${summary.critical}</div>
|
|
335
|
+
<div class="label">Critical</div>
|
|
336
|
+
</div>
|
|
337
|
+
<div class="summary-item high">
|
|
338
|
+
<div class="count">${summary.high}</div>
|
|
339
|
+
<div class="label">High</div>
|
|
340
|
+
</div>
|
|
341
|
+
<div class="summary-item medium">
|
|
342
|
+
<div class="count">${summary.medium}</div>
|
|
343
|
+
<div class="label">Medium</div>
|
|
344
|
+
</div>
|
|
345
|
+
<div class="summary-item low">
|
|
346
|
+
<div class="count">${summary.low}</div>
|
|
347
|
+
<div class="label">Low</div>
|
|
348
|
+
</div>
|
|
349
|
+
<div class="summary-item info">
|
|
350
|
+
<div class="count">${summary.info}</div>
|
|
351
|
+
<div class="label">Info</div>
|
|
352
|
+
</div>
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
|
|
356
|
+
<div class="card">
|
|
357
|
+
<h2>Vulnerabilities</h2>
|
|
358
|
+
${vulnerabilities.map(vuln => `
|
|
359
|
+
<div class="vuln ${vuln.severity}">
|
|
360
|
+
<div class="vuln-title">
|
|
361
|
+
<span class="badge ${vuln.severity}">${vuln.severity.toUpperCase()}</span>
|
|
362
|
+
${this.escapeHtml(vuln.type)}
|
|
363
|
+
</div>
|
|
364
|
+
<div class="vuln-meta">
|
|
365
|
+
${this.escapeHtml(vuln.location.file)}:${vuln.location.startLine} |
|
|
366
|
+
${vuln.cwes[0] ?? 'N/A'} |
|
|
367
|
+
${vuln.owasp?.[0] ?? 'N/A'}
|
|
368
|
+
</div>
|
|
369
|
+
<p>${this.escapeHtml(vuln.description)}</p>
|
|
370
|
+
${vuln.codeSnippet && this.config.includeCode ? `<pre>${this.escapeHtml(vuln.codeSnippet)}</pre>` : ''}
|
|
371
|
+
${vuln.recommendation ? `<p><strong>Remediation:</strong> ${this.escapeHtml(vuln.recommendation)}</p>` : ''}
|
|
372
|
+
</div>
|
|
373
|
+
`).join('')}
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
376
|
+
</body>
|
|
377
|
+
</html>`;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Generate summary statistics
|
|
381
|
+
*/
|
|
382
|
+
generateSummary(results) {
|
|
383
|
+
const vulns = results.vulnerabilities.vulnerabilities;
|
|
384
|
+
const summary = {
|
|
385
|
+
critical: 0,
|
|
386
|
+
high: 0,
|
|
387
|
+
medium: 0,
|
|
388
|
+
low: 0,
|
|
389
|
+
info: 0,
|
|
390
|
+
total: vulns.length,
|
|
391
|
+
};
|
|
392
|
+
for (const vuln of vulns) {
|
|
393
|
+
summary[vuln.severity]++;
|
|
394
|
+
}
|
|
395
|
+
return summary;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Format vulnerabilities based on config
|
|
399
|
+
*/
|
|
400
|
+
formatVulnerabilities(vulnerabilities) {
|
|
401
|
+
let formatted = [...vulnerabilities];
|
|
402
|
+
// Sort
|
|
403
|
+
if (this.config.sortBy === 'severity') {
|
|
404
|
+
const severityOrder = {
|
|
405
|
+
critical: 0,
|
|
406
|
+
high: 1,
|
|
407
|
+
medium: 2,
|
|
408
|
+
low: 3,
|
|
409
|
+
info: 4,
|
|
410
|
+
};
|
|
411
|
+
formatted.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
412
|
+
}
|
|
413
|
+
else if (this.config.sortBy === 'file') {
|
|
414
|
+
formatted.sort((a, b) => a.location.file.localeCompare(b.location.file));
|
|
415
|
+
}
|
|
416
|
+
return formatted;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Group vulnerabilities by severity
|
|
420
|
+
*/
|
|
421
|
+
groupBySeverity(vulnerabilities) {
|
|
422
|
+
const grouped = new Map();
|
|
423
|
+
for (const vuln of vulnerabilities) {
|
|
424
|
+
const list = grouped.get(vuln.severity) || [];
|
|
425
|
+
list.push(vuln);
|
|
426
|
+
grouped.set(vuln.severity, list);
|
|
427
|
+
}
|
|
428
|
+
return grouped;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Convert severity to SARIF level
|
|
432
|
+
*/
|
|
433
|
+
severityToSARIFLevel(severity) {
|
|
434
|
+
switch (severity) {
|
|
435
|
+
case 'critical':
|
|
436
|
+
case 'high':
|
|
437
|
+
return 'error';
|
|
438
|
+
case 'medium':
|
|
439
|
+
return 'warning';
|
|
440
|
+
case 'low':
|
|
441
|
+
case 'info':
|
|
442
|
+
return 'note';
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Escape HTML entities
|
|
447
|
+
*/
|
|
448
|
+
escapeHtml(str) {
|
|
449
|
+
return str
|
|
450
|
+
.replace(/&/g, '&')
|
|
451
|
+
.replace(/</g, '<')
|
|
452
|
+
.replace(/>/g, '>')
|
|
453
|
+
.replace(/"/g, '"')
|
|
454
|
+
.replace(/'/g, ''');
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Create a report generator
|
|
459
|
+
*/
|
|
460
|
+
export function createReportGenerator(config) {
|
|
461
|
+
return new ReportGenerator(config);
|
|
462
|
+
}
|
|
463
|
+
//# sourceMappingURL=report-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-generator.js","sourceRoot":"","sources":["../../src/services/report-generator.ts"],"names":[],"mappings":"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"}
|