coverme-security-scanner 3.4.0 → 3.7.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/bin/merge-reports.js +231 -0
- package/commands/coverme.md +88 -195
- package/package.json +2 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Merge multiple partial security reports into a single comprehensive report
|
|
5
|
+
* Usage: coverme-merge .coverme/partial-*.json -o scan.json
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync, writeFileSync, readdirSync } from 'fs';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
|
+
|
|
11
|
+
function mergeReports(inputDir, outputFile) {
|
|
12
|
+
const files = readdirSync(inputDir).filter(f => f.startsWith('partial-') && f.endsWith('.json'));
|
|
13
|
+
|
|
14
|
+
if (files.length === 0) {
|
|
15
|
+
console.error('No partial-*.json files found in', inputDir);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
console.log(`Merging ${files.length} partial reports...`);
|
|
20
|
+
|
|
21
|
+
// Initialize merged report
|
|
22
|
+
const merged = {
|
|
23
|
+
project: '',
|
|
24
|
+
date: new Date().toISOString().split('T')[0],
|
|
25
|
+
branch: '',
|
|
26
|
+
scope: '',
|
|
27
|
+
methodology: '7 parallel security agents with attack chain analysis',
|
|
28
|
+
summary: { critical: 0, high: 0, medium: 0, low: 0, total: 0 },
|
|
29
|
+
overallRiskLevel: 'low',
|
|
30
|
+
executiveSummary: '',
|
|
31
|
+
topPriorities: [],
|
|
32
|
+
attackChains: [],
|
|
33
|
+
riskMatrix: [],
|
|
34
|
+
architecture: { overview: '', components: [], trustBoundaries: [] },
|
|
35
|
+
network: { diagram: '', ports: [], externalDeps: [] },
|
|
36
|
+
findings: [],
|
|
37
|
+
threatModel: [],
|
|
38
|
+
positiveObservations: [],
|
|
39
|
+
complianceMapping: [],
|
|
40
|
+
remediation: { p0: [], p1: [], p2: [], p3: [] },
|
|
41
|
+
qualityReview: { deadCode: [], dryViolations: [], deprecated: [] },
|
|
42
|
+
resolvedIssues: [],
|
|
43
|
+
privacyAnalysis: []
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Process each partial file
|
|
47
|
+
for (const file of files) {
|
|
48
|
+
const filePath = join(inputDir, file);
|
|
49
|
+
console.log(` Processing: ${file}`);
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const partial = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
53
|
+
|
|
54
|
+
// Merge simple fields (take first non-empty value)
|
|
55
|
+
if (partial.project && !merged.project) merged.project = partial.project;
|
|
56
|
+
if (partial.date) merged.date = partial.date;
|
|
57
|
+
if (partial.branch && !merged.branch) merged.branch = partial.branch;
|
|
58
|
+
if (partial.scope && !merged.scope) merged.scope = partial.scope;
|
|
59
|
+
if (partial.executiveSummary && !merged.executiveSummary) {
|
|
60
|
+
merged.executiveSummary = partial.executiveSummary;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Merge arrays (deduplicate by id where applicable)
|
|
64
|
+
if (partial.findings) {
|
|
65
|
+
for (const f of partial.findings) {
|
|
66
|
+
if (!merged.findings.find(x => x.id === f.id)) {
|
|
67
|
+
merged.findings.push(f);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (partial.attackChains) {
|
|
73
|
+
for (const ac of partial.attackChains) {
|
|
74
|
+
if (!merged.attackChains.find(x => x.id === ac.id)) {
|
|
75
|
+
merged.attackChains.push(ac);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (partial.topPriorities) {
|
|
81
|
+
merged.topPriorities.push(...partial.topPriorities);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (partial.riskMatrix) {
|
|
85
|
+
for (const rm of partial.riskMatrix) {
|
|
86
|
+
if (!merged.riskMatrix.find(x => x.category === rm.category)) {
|
|
87
|
+
merged.riskMatrix.push(rm);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (partial.architecture) {
|
|
93
|
+
if (partial.architecture.overview && !merged.architecture.overview) {
|
|
94
|
+
merged.architecture.overview = partial.architecture.overview;
|
|
95
|
+
}
|
|
96
|
+
if (partial.architecture.components) {
|
|
97
|
+
merged.architecture.components.push(...partial.architecture.components);
|
|
98
|
+
}
|
|
99
|
+
if (partial.architecture.trustBoundaries) {
|
|
100
|
+
merged.architecture.trustBoundaries.push(...partial.architecture.trustBoundaries);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (partial.network) {
|
|
105
|
+
if (partial.network.diagram && !merged.network.diagram) {
|
|
106
|
+
merged.network.diagram = partial.network.diagram;
|
|
107
|
+
}
|
|
108
|
+
if (partial.network.ports) {
|
|
109
|
+
for (const p of partial.network.ports) {
|
|
110
|
+
if (!merged.network.ports.find(x => x.port === p.port)) {
|
|
111
|
+
merged.network.ports.push(p);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (partial.network.externalDeps) {
|
|
116
|
+
merged.network.externalDeps.push(...partial.network.externalDeps);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (partial.threatModel) {
|
|
121
|
+
for (const tm of partial.threatModel) {
|
|
122
|
+
if (!merged.threatModel.find(x => x.id === tm.id)) {
|
|
123
|
+
merged.threatModel.push(tm);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (partial.positiveObservations) {
|
|
129
|
+
merged.positiveObservations.push(...partial.positiveObservations);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (partial.complianceMapping) {
|
|
133
|
+
for (const cm of partial.complianceMapping) {
|
|
134
|
+
const existing = merged.complianceMapping.find(x => x.framework === cm.framework);
|
|
135
|
+
if (existing) {
|
|
136
|
+
existing.controls.push(...cm.controls);
|
|
137
|
+
} else {
|
|
138
|
+
merged.complianceMapping.push(cm);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (partial.remediation) {
|
|
144
|
+
if (partial.remediation.p0) merged.remediation.p0.push(...partial.remediation.p0);
|
|
145
|
+
if (partial.remediation.p1) merged.remediation.p1.push(...partial.remediation.p1);
|
|
146
|
+
if (partial.remediation.p2) merged.remediation.p2.push(...partial.remediation.p2);
|
|
147
|
+
if (partial.remediation.p3) merged.remediation.p3.push(...partial.remediation.p3);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (partial.qualityReview) {
|
|
151
|
+
if (partial.qualityReview.deadCode) {
|
|
152
|
+
merged.qualityReview.deadCode.push(...partial.qualityReview.deadCode);
|
|
153
|
+
}
|
|
154
|
+
if (partial.qualityReview.dryViolations) {
|
|
155
|
+
merged.qualityReview.dryViolations.push(...partial.qualityReview.dryViolations);
|
|
156
|
+
}
|
|
157
|
+
if (partial.qualityReview.deprecated) {
|
|
158
|
+
merged.qualityReview.deprecated.push(...partial.qualityReview.deprecated);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (partial.resolvedIssues) {
|
|
163
|
+
merged.resolvedIssues.push(...partial.resolvedIssues);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (partial.privacyAnalysis) {
|
|
167
|
+
merged.privacyAnalysis.push(...partial.privacyAnalysis);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
} catch (e) {
|
|
171
|
+
console.error(` Error parsing ${file}:`, e.message);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Calculate summary counts
|
|
176
|
+
merged.summary.critical = merged.findings.filter(f => f.severity === 'critical').length;
|
|
177
|
+
merged.summary.high = merged.findings.filter(f => f.severity === 'high').length;
|
|
178
|
+
merged.summary.medium = merged.findings.filter(f => f.severity === 'medium').length;
|
|
179
|
+
merged.summary.low = merged.findings.filter(f => f.severity === 'low').length;
|
|
180
|
+
merged.summary.total = merged.findings.length;
|
|
181
|
+
|
|
182
|
+
// Determine overall risk level
|
|
183
|
+
if (merged.summary.critical > 0) {
|
|
184
|
+
merged.overallRiskLevel = 'critical';
|
|
185
|
+
} else if (merged.summary.high > 2) {
|
|
186
|
+
merged.overallRiskLevel = 'high';
|
|
187
|
+
} else if (merged.summary.high > 0 || merged.summary.medium > 3) {
|
|
188
|
+
merged.overallRiskLevel = 'medium';
|
|
189
|
+
} else {
|
|
190
|
+
merged.overallRiskLevel = 'low';
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Deduplicate top priorities (keep first 5)
|
|
194
|
+
const seenPriorities = new Set();
|
|
195
|
+
merged.topPriorities = merged.topPriorities.filter(p => {
|
|
196
|
+
if (seenPriorities.has(p.finding)) return false;
|
|
197
|
+
seenPriorities.add(p.finding);
|
|
198
|
+
return true;
|
|
199
|
+
}).slice(0, 5);
|
|
200
|
+
|
|
201
|
+
// Remove empty arrays
|
|
202
|
+
if (merged.qualityReview.deadCode.length === 0 &&
|
|
203
|
+
merged.qualityReview.dryViolations.length === 0 &&
|
|
204
|
+
merged.qualityReview.deprecated.length === 0) {
|
|
205
|
+
delete merged.qualityReview;
|
|
206
|
+
}
|
|
207
|
+
if (merged.resolvedIssues.length === 0) delete merged.resolvedIssues;
|
|
208
|
+
if (merged.privacyAnalysis.length === 0) delete merged.privacyAnalysis;
|
|
209
|
+
|
|
210
|
+
// Write merged report
|
|
211
|
+
writeFileSync(outputFile, JSON.stringify(merged, null, 2));
|
|
212
|
+
console.log(`\nMerged report written to: ${outputFile}`);
|
|
213
|
+
console.log(` Total findings: ${merged.summary.total}`);
|
|
214
|
+
console.log(` Critical: ${merged.summary.critical}, High: ${merged.summary.high}, Medium: ${merged.summary.medium}, Low: ${merged.summary.low}`);
|
|
215
|
+
console.log(` Attack chains: ${merged.attackChains.length}`);
|
|
216
|
+
console.log(` Overall risk: ${merged.overallRiskLevel.toUpperCase()}`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// CLI
|
|
220
|
+
const args = process.argv.slice(2);
|
|
221
|
+
if (args.length < 1) {
|
|
222
|
+
console.log('Usage: coverme-merge <input-dir> [output-file]');
|
|
223
|
+
console.log(' input-dir: Directory containing partial-*.json files');
|
|
224
|
+
console.log(' output-file: Output file (default: scan.json)');
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const inputDir = args[0];
|
|
229
|
+
const outputFile = args[1] || 'scan.json';
|
|
230
|
+
|
|
231
|
+
mergeReports(inputDir, outputFile);
|
package/commands/coverme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Security Assessment Generator
|
|
1
|
+
# Security Assessment Generator v3
|
|
2
2
|
|
|
3
3
|
Run a comprehensive security assessment on this codebase and generate a professional PDF report with deep analysis.
|
|
4
4
|
|
|
@@ -6,23 +6,31 @@ Run a comprehensive security assessment on this codebase and generate a professi
|
|
|
6
6
|
|
|
7
7
|
You are a senior security architect and penetration tester performing a pre-production security audit. Run 7 parallel security agents to analyze this codebase comprehensively.
|
|
8
8
|
|
|
9
|
+
### Step 0: Setup (Run First!)
|
|
10
|
+
|
|
11
|
+
Before starting the scan, create the output directory:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
mkdir -p .coverme
|
|
15
|
+
```
|
|
16
|
+
|
|
9
17
|
### Step 1: Launch Parallel Agents
|
|
10
18
|
|
|
11
|
-
Launch these 7 agents simultaneously using the Task tool:
|
|
19
|
+
Launch these 7 agents simultaneously using the Task tool. **IMPORTANT: Each agent must write its own partial JSON file immediately when done.**
|
|
12
20
|
|
|
13
21
|
1. **Executive Summary Agent** (subagent_type: Explore)
|
|
14
22
|
- Understand what the system does
|
|
15
23
|
- Identify the tech stack and architecture
|
|
16
24
|
- Map trust boundaries and critical assets
|
|
17
25
|
- Determine overall risk level
|
|
18
|
-
-
|
|
26
|
+
- **When done: Write findings to `.coverme/partial-01-executive.json`**
|
|
19
27
|
|
|
20
28
|
2. **Attack Surface Agent** (subagent_type: Explore)
|
|
21
29
|
- Map all entry points (APIs, webhooks, file uploads, CLI args)
|
|
22
30
|
- Identify unauthenticated endpoints
|
|
23
31
|
- Find admin/debug interfaces
|
|
24
|
-
- Check for exposed internal services
|
|
25
32
|
- Document external dependencies and their trust level
|
|
33
|
+
- **When done: Write findings to `.coverme/partial-02-attack-surface.json`**
|
|
26
34
|
|
|
27
35
|
3. **Vulnerability Hunter Agent** (subagent_type: Explore)
|
|
28
36
|
- OWASP Top 10 deep dive with CODE EVIDENCE
|
|
@@ -30,121 +38,37 @@ Launch these 7 agents simultaneously using the Task tool:
|
|
|
30
38
|
- Authentication/authorization bypass paths
|
|
31
39
|
- Injection vulnerabilities (SQL, command, XSS, SSTI)
|
|
32
40
|
- Secrets in code, hardcoded credentials (show exact lines)
|
|
33
|
-
-
|
|
34
|
-
- Rate limiting gaps, brute force opportunities
|
|
41
|
+
- **When done: Write findings to `.coverme/partial-03-vulnerabilities.json`**
|
|
35
42
|
|
|
36
43
|
4. **Attack Chain Analyst Agent** (subagent_type: Explore)
|
|
37
44
|
- Identify how vulnerabilities COMBINE for greater impact
|
|
38
45
|
- Map realistic attack scenarios (entry -> pivot -> objective)
|
|
39
46
|
- Calculate blast radius for each chain
|
|
40
|
-
-
|
|
41
|
-
- Prioritize chains by likelihood and impact
|
|
47
|
+
- **When done: Write findings to `.coverme/partial-04-attack-chains.json`**
|
|
42
48
|
|
|
43
49
|
5. **Business Logic Agent** (subagent_type: Explore)
|
|
44
50
|
- Race conditions in critical flows (payments, credits, locks)
|
|
45
51
|
- Workflow bypass opportunities (skip steps, replay)
|
|
46
52
|
- Credit/billing manipulation vectors
|
|
47
|
-
- Data validation gaps at business boundaries
|
|
48
|
-
- PII handling and data residency violations
|
|
49
53
|
- Privilege escalation paths
|
|
54
|
+
- **When done: Write findings to `.coverme/partial-05-business-logic.json`**
|
|
50
55
|
|
|
51
56
|
6. **Infrastructure Agent** (subagent_type: Explore)
|
|
52
57
|
- Docker/Kubernetes security (securityContext, network policies)
|
|
53
58
|
- CI/CD pipeline security gates (or lack thereof)
|
|
54
59
|
- Secrets management (env vars, mounted secrets, hardcoded)
|
|
55
|
-
- Cloud configuration (IAM, S3 buckets, security groups)
|
|
56
|
-
- Database security (encryption, access controls)
|
|
57
60
|
- Dependency vulnerabilities (npm audit, CVEs)
|
|
61
|
+
- **When done: Write findings to `.coverme/partial-06-infrastructure.json`**
|
|
58
62
|
|
|
59
63
|
7. **Compliance & Impact Agent** (subagent_type: Explore)
|
|
60
|
-
- Map findings to compliance frameworks (SOC2, PCI-DSS, GDPR
|
|
64
|
+
- Map findings to compliance frameworks (SOC2, PCI-DSS, GDPR)
|
|
61
65
|
- Calculate business impact for each critical finding
|
|
62
66
|
- Estimate financial exposure ranges
|
|
63
|
-
-
|
|
64
|
-
- Determine data breach notification requirements
|
|
65
|
-
|
|
66
|
-
### Step 2: Deep Dive on Findings
|
|
67
|
-
|
|
68
|
-
For EVERY critical and high finding, ensure you have:
|
|
69
|
-
|
|
70
|
-
1. **Code Evidence** - The EXACT vulnerable code snippet:
|
|
71
|
-
```
|
|
72
|
-
"codeEvidence": [{
|
|
73
|
-
"file": "src/auth/login.js",
|
|
74
|
-
"startLine": 45,
|
|
75
|
-
"endLine": 52,
|
|
76
|
-
"code": "const user = await db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);",
|
|
77
|
-
"annotation": "User input directly interpolated into SQL query"
|
|
78
|
-
}]
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
2. **Exploitability Assessment**:
|
|
82
|
-
```
|
|
83
|
-
"exploitability": {
|
|
84
|
-
"skillLevel": "novice", // novice/intermediate/expert
|
|
85
|
-
"accessRequired": "network", // network/adjacent/local/physical
|
|
86
|
-
"authRequired": "none", // none/low/high
|
|
87
|
-
"userInteraction": "none", // none/required
|
|
88
|
-
"hasPublicExploit": true, // Known PoC exists?
|
|
89
|
-
"exploitMaturity": "weaponized", // theoretical/poc/weaponized
|
|
90
|
-
"automatable": true // Can be mass-exploited?
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
3. **Blast Radius**:
|
|
95
|
-
```
|
|
96
|
-
"blastRadius": {
|
|
97
|
-
"affectedUsers": "all", // none/single/subset/all
|
|
98
|
-
"affectedData": ["PII", "credentials", "financial"],
|
|
99
|
-
"affectedServices": ["auth", "payments"],
|
|
100
|
-
"cascadeRisk": true, // Leads to further compromise?
|
|
101
|
-
"containment": "system" // isolated/component/system/infrastructure
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
4. **Business Impact**:
|
|
106
|
-
```
|
|
107
|
-
"businessImpact": {
|
|
108
|
-
"confidentiality": "high",
|
|
109
|
-
"integrity": "high",
|
|
110
|
-
"availability": "low",
|
|
111
|
-
"financialExposure": "$100k-$1M potential fraud",
|
|
112
|
-
"complianceViolations": ["PCI-DSS 6.5.1", "SOC2 CC6.1"],
|
|
113
|
-
"reputationalRisk": "high",
|
|
114
|
-
"slaImpact": "99.9% SLA at risk"
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
5. **Proof of Concept** (safe, non-destructive):
|
|
119
|
-
```
|
|
120
|
-
"proofOfConcept": "curl -X POST /api/admin/users -H 'X-Admin: true' -d '{\"role\":\"admin\"}'"
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Step 3: Build Attack Chains
|
|
124
|
-
|
|
125
|
-
Identify 2-5 realistic attack chains that combine multiple vulnerabilities:
|
|
126
|
-
|
|
127
|
-
```json
|
|
128
|
-
"attackChains": [
|
|
129
|
-
{
|
|
130
|
-
"id": "AC-01",
|
|
131
|
-
"name": "Credential Theft to Full Infrastructure Compromise",
|
|
132
|
-
"description": "Attacker chains unauthenticated endpoint access with hardcoded secrets to gain full system control",
|
|
133
|
-
"likelihood": "high",
|
|
134
|
-
"impact": "critical",
|
|
135
|
-
"steps": [
|
|
136
|
-
{ "order": 1, "findingId": "HIGH-02", "action": "Access unauthenticated /enclave/register endpoint", "outcome": "Register malicious enclave with attacker-controlled keys" },
|
|
137
|
-
{ "order": 2, "findingId": "HIGH-01", "action": "Use leaked tracker API key from Helm values", "outcome": "Gain access to usage analytics and user activity" },
|
|
138
|
-
{ "order": 3, "findingId": "CRIT-01", "action": "Pivot using AWS credentials from .env", "outcome": "Full AWS account access, S3 data exfiltration" }
|
|
139
|
-
],
|
|
140
|
-
"mitigationStrategy": "Breaking any link stops the chain. Priority: rotate AWS credentials immediately."
|
|
141
|
-
}
|
|
142
|
-
]
|
|
143
|
-
```
|
|
67
|
+
- **When done: Write findings to `.coverme/partial-07-compliance.json`**
|
|
144
68
|
|
|
145
|
-
###
|
|
69
|
+
### Agent Output Format
|
|
146
70
|
|
|
147
|
-
|
|
71
|
+
Each agent should write a partial JSON with this structure (include only relevant fields):
|
|
148
72
|
|
|
149
73
|
```json
|
|
150
74
|
{
|
|
@@ -152,40 +76,10 @@ After all agents complete, compile their findings into a JSON file with this enh
|
|
|
152
76
|
"date": "YYYY-MM-DD",
|
|
153
77
|
"branch": "branch-name",
|
|
154
78
|
"scope": "X files, ~Y lines",
|
|
155
|
-
"
|
|
156
|
-
|
|
157
|
-
"summary": {
|
|
158
|
-
"critical": 0,
|
|
159
|
-
"high": 0,
|
|
160
|
-
"medium": 0,
|
|
161
|
-
"low": 0,
|
|
162
|
-
"total": 0
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
"overallRiskLevel": "critical|high|medium|low",
|
|
166
|
-
"executiveSummary": "2-3 paragraphs: what the system does, key findings, recommended actions...",
|
|
79
|
+
"executiveSummary": "Summary paragraph...",
|
|
167
80
|
|
|
168
81
|
"topPriorities": [
|
|
169
|
-
{ "finding": "Description", "severity": "critical", "action": "
|
|
170
|
-
],
|
|
171
|
-
|
|
172
|
-
"attackChains": [
|
|
173
|
-
{
|
|
174
|
-
"id": "AC-01",
|
|
175
|
-
"name": "Chain name",
|
|
176
|
-
"description": "How vulnerabilities combine",
|
|
177
|
-
"likelihood": "high",
|
|
178
|
-
"impact": "critical",
|
|
179
|
-
"steps": [
|
|
180
|
-
{ "order": 1, "findingId": "CRIT-01", "action": "What attacker does", "outcome": "What they achieve" }
|
|
181
|
-
],
|
|
182
|
-
"mitigationStrategy": "How to break the chain"
|
|
183
|
-
}
|
|
184
|
-
],
|
|
185
|
-
|
|
186
|
-
"riskMatrix": [
|
|
187
|
-
{ "category": "Authentication", "currentRisk": "high", "residualRisk": "low", "trend": "stable" },
|
|
188
|
-
{ "category": "Data Protection", "currentRisk": "medium", "residualRisk": "low", "trend": "improving" }
|
|
82
|
+
{ "finding": "Description", "severity": "critical", "action": "Action needed" }
|
|
189
83
|
],
|
|
190
84
|
|
|
191
85
|
"architecture": {
|
|
@@ -194,7 +88,7 @@ After all agents complete, compile their findings into a JSON file with this enh
|
|
|
194
88
|
{ "name": "Component", "technology": "Tech", "description": "Purpose" }
|
|
195
89
|
],
|
|
196
90
|
"trustBoundaries": [
|
|
197
|
-
{ "id": "TB-01", "boundary": "
|
|
91
|
+
{ "id": "TB-01", "boundary": "Name", "trustLevel": "untrusted", "description": "..." }
|
|
198
92
|
]
|
|
199
93
|
},
|
|
200
94
|
|
|
@@ -202,9 +96,6 @@ After all agents complete, compile their findings into a JSON file with this enh
|
|
|
202
96
|
"diagram": "ASCII diagram...",
|
|
203
97
|
"ports": [
|
|
204
98
|
{ "port": 443, "protocol": "HTTPS", "component": "API", "binding": "0.0.0.0", "purpose": "Public API" }
|
|
205
|
-
],
|
|
206
|
-
"externalDeps": [
|
|
207
|
-
{ "service": "Stripe", "endpoint": "api.stripe.com", "auth": "API key", "risk": "PCI scope" }
|
|
208
99
|
]
|
|
209
100
|
},
|
|
210
101
|
|
|
@@ -221,58 +112,40 @@ After all agents complete, compile their findings into a JSON file with this enh
|
|
|
221
112
|
"status": "open",
|
|
222
113
|
"dreadScore": 8.5,
|
|
223
114
|
"cwe": "CWE-89",
|
|
224
|
-
"
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
],
|
|
235
|
-
"exploitability": {
|
|
236
|
-
"skillLevel": "novice",
|
|
237
|
-
"accessRequired": "network",
|
|
238
|
-
"authRequired": "none",
|
|
239
|
-
"userInteraction": "none",
|
|
240
|
-
"hasPublicExploit": true,
|
|
241
|
-
"exploitMaturity": "weaponized",
|
|
242
|
-
"automatable": true
|
|
243
|
-
},
|
|
244
|
-
"blastRadius": {
|
|
245
|
-
"affectedUsers": "all",
|
|
246
|
-
"affectedData": ["PII", "credentials"],
|
|
247
|
-
"affectedServices": ["database", "auth"],
|
|
248
|
-
"cascadeRisk": true,
|
|
249
|
-
"containment": "system"
|
|
250
|
-
},
|
|
251
|
-
"businessImpact": {
|
|
252
|
-
"confidentiality": "high",
|
|
253
|
-
"integrity": "high",
|
|
254
|
-
"availability": "none",
|
|
255
|
-
"financialExposure": "$500k-$5M breach costs",
|
|
256
|
-
"complianceViolations": ["GDPR Art 32", "SOC2 CC6.1"],
|
|
257
|
-
"reputationalRisk": "high"
|
|
258
|
-
},
|
|
259
|
-
"proofOfConcept": "curl '/api/users/1 OR 1=1--'",
|
|
260
|
-
"relatedFindings": ["HIGH-02", "HIGH-03"],
|
|
261
|
-
"attackChainPosition": "entry",
|
|
262
|
-
"references": ["https://owasp.org/Top10/A03_2021-Injection/"]
|
|
115
|
+
"codeEvidence": [{
|
|
116
|
+
"file": "src/file.js",
|
|
117
|
+
"startLine": 45,
|
|
118
|
+
"endLine": 50,
|
|
119
|
+
"code": "vulnerable code here",
|
|
120
|
+
"annotation": "Explanation"
|
|
121
|
+
}],
|
|
122
|
+
"proofOfConcept": "curl command or steps",
|
|
123
|
+
"relatedFindings": ["HIGH-02"]
|
|
263
124
|
}
|
|
264
125
|
],
|
|
265
126
|
|
|
266
|
-
"
|
|
127
|
+
"attackChains": [
|
|
267
128
|
{
|
|
268
|
-
"id": "
|
|
269
|
-
"
|
|
270
|
-
"
|
|
271
|
-
"
|
|
272
|
-
"
|
|
129
|
+
"id": "AC-01",
|
|
130
|
+
"name": "Chain name",
|
|
131
|
+
"description": "How vulnerabilities combine",
|
|
132
|
+
"likelihood": "high",
|
|
133
|
+
"impact": "critical",
|
|
134
|
+
"steps": [
|
|
135
|
+
{ "order": 1, "findingId": "CRIT-01", "action": "What attacker does", "outcome": "Result" }
|
|
136
|
+
],
|
|
137
|
+
"mitigationStrategy": "How to break the chain"
|
|
273
138
|
}
|
|
274
139
|
],
|
|
275
140
|
|
|
141
|
+
"riskMatrix": [
|
|
142
|
+
{ "category": "Authentication", "currentRisk": "high", "residualRisk": "low", "trend": "stable" }
|
|
143
|
+
],
|
|
144
|
+
|
|
145
|
+
"threatModel": [
|
|
146
|
+
{ "id": "T-01", "severity": "high", "dread": 6.5, "status": "open", "finding": "Description" }
|
|
147
|
+
],
|
|
148
|
+
|
|
276
149
|
"positiveObservations": [
|
|
277
150
|
{ "title": "Good Practice", "description": "What they did right..." }
|
|
278
151
|
],
|
|
@@ -288,43 +161,63 @@ After all agents complete, compile their findings into a JSON file with this enh
|
|
|
288
161
|
|
|
289
162
|
"remediation": {
|
|
290
163
|
"p0": [{ "action": "Do this NOW", "finding": "CRIT-01", "owner": "Security" }],
|
|
291
|
-
"p1": [{ "action": "Do this week", "finding": "HIGH-01", "owner": "Backend" }]
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
164
|
+
"p1": [{ "action": "Do this week", "finding": "HIGH-01", "owner": "Backend" }]
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
"qualityReview": {
|
|
168
|
+
"deadCode": [{ "type": "dead-code", "action": "DELETE", "file": "path", "description": "..." }],
|
|
169
|
+
"dryViolations": [{ "type": "dry-violation", "action": "MERGE", "file": "path", "description": "..." }]
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
"privacyAnalysis": [
|
|
173
|
+
{ "category": "Linkability", "risk": "medium", "description": "...", "mitigation": "..." }
|
|
174
|
+
]
|
|
295
175
|
}
|
|
296
176
|
```
|
|
297
177
|
|
|
298
|
-
### Step
|
|
178
|
+
### Step 2: Wait for All Agents and Verify
|
|
179
|
+
|
|
180
|
+
After launching all agents, wait for them to complete. Then verify all partial files exist:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
ls -la .coverme/partial-*.json
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
You should see 7 files (partial-01 through partial-07).
|
|
187
|
+
|
|
188
|
+
### Step 3: Merge and Generate PDF
|
|
299
189
|
|
|
300
|
-
|
|
190
|
+
Once all 7 partial files are written, merge them and generate the PDF:
|
|
301
191
|
|
|
302
192
|
```bash
|
|
303
|
-
coverme .coverme/scan.json security-assessment-$(date +%Y-%m-%d).pdf && open security-assessment-$(date +%Y-%m-%d).pdf
|
|
193
|
+
coverme-merge .coverme && coverme .coverme/scan.json security-assessment-$(date +%Y-%m-%d).pdf && open security-assessment-$(date +%Y-%m-%d).pdf
|
|
304
194
|
```
|
|
305
195
|
|
|
306
|
-
|
|
196
|
+
This command:
|
|
197
|
+
1. Merges all partial-*.json files into scan.json
|
|
198
|
+
2. Generates the PDF report
|
|
199
|
+
3. Opens it automatically
|
|
307
200
|
|
|
308
201
|
### Quality Checklist
|
|
309
202
|
|
|
310
203
|
Before generating the PDF, verify:
|
|
204
|
+
- [ ] All 7 partial JSON files exist in .coverme/
|
|
311
205
|
- [ ] Every CRITICAL/HIGH finding has codeEvidence with actual code
|
|
312
|
-
- [ ] Every CRITICAL/HIGH finding has exploitability assessment
|
|
313
|
-
- [ ] Every CRITICAL/HIGH finding has blastRadius defined
|
|
314
206
|
- [ ] At least 2 attack chains are documented
|
|
315
|
-
- [ ] Top priorities match the most impactful attack chains
|
|
316
|
-
- [ ] Proof of concepts are safe and non-destructive
|
|
317
207
|
- [ ] CWE IDs are accurate for vulnerability types
|
|
318
|
-
- [ ] Compliance violations are specific (e.g., "PCI-DSS 6.5.1" not just "PCI-DSS")
|
|
319
208
|
|
|
320
209
|
### Output
|
|
321
210
|
|
|
322
|
-
The final
|
|
323
|
-
1. `.coverme/
|
|
324
|
-
2.
|
|
211
|
+
The final deliverables are:
|
|
212
|
+
1. `.coverme/partial-*.json` - Individual agent reports
|
|
213
|
+
2. `.coverme/scan.json` - Merged comprehensive report
|
|
214
|
+
3. `security-assessment-YYYY-MM-DD.pdf` - Professional PDF report
|
|
325
215
|
|
|
326
216
|
---
|
|
327
217
|
|
|
328
|
-
Now begin the security assessment
|
|
218
|
+
Now begin the security assessment:
|
|
329
219
|
|
|
330
|
-
|
|
220
|
+
1. Run `mkdir -p .coverme`
|
|
221
|
+
2. Launch all 7 agents in parallel
|
|
222
|
+
3. Each agent writes its own partial JSON when done
|
|
223
|
+
4. After all complete, run the merge and PDF generation command
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coverme-security-scanner",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "AI-powered security assessment reports with beautiful PDF output",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"coverme": "./bin/coverme.js",
|
|
8
|
+
"coverme-merge": "./bin/merge-reports.js",
|
|
8
9
|
"coverme-install": "./bin/install-command.js"
|
|
9
10
|
},
|
|
10
11
|
"main": "./dist/index.js",
|