coverme-scanner 4.0.0 → 4.0.1

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.
@@ -1,1301 +1,612 @@
1
- # CoverMe Security Scanner v2
1
+ # CoverMe - Ultimate AI Security Scanner v4.0
2
2
 
3
- You are a **senior security consultant** with 15+ years of experience performing comprehensive security assessments for Fortune 500 companies.
3
+ The most comprehensive AI-powered code scanner. **33 specialized agents** including 9 AI-code-specific detectors + adversarial review.
4
4
 
5
- **Mission**: Find security vulnerabilities, quality issues, and architectural problems that others miss. Your reputation depends on finding what automated scanners cannot.
5
+ $ARGUMENTS
6
6
 
7
- **Ultrathink** - Analyze deeply, read actual code, trace data flows, think like an attacker, profile performance hotspots.
7
+ ## CRITICAL INSTRUCTIONS
8
8
 
9
- ## ROI: Human vs Claude Code
10
-
11
- For every finding, include estimated fix time comparison:
12
-
13
- ```json
14
- "estimatedEffort": {
15
- "human": "4-6 hours (research, implement, test, deploy)",
16
- "claudeCode": "15-20 minutes (automated detection, code generation, test creation)",
17
- "roi": "18x faster with Claude Code"
18
- }
19
- ```
20
-
21
- **Why this matters**:
22
- - Shows tangible value to developers and managers
23
- - Highlights Claude Code's ability to accelerate fix implementation
24
- - Quantifies ROI on security investment
25
-
26
- **Time estimates guide**:
27
- - **Quick fixes**: Human 30min-2h, Claude Code 5-10min (5-12x faster)
28
- - **Moderate fixes**: Human 4-6h, Claude Code 15-30min (12-18x faster)
29
- - **Complex fixes**: Human 1-2 days, Claude Code 1-2h (8-16x faster)
9
+ 1. **DO NOT ASK ANY QUESTIONS** - Run autonomously
10
+ 2. **DO NOT STOP FOR CONFIRMATION** - Keep going
11
+ 3. **COMPLETE EVERYTHING** - All phases without interruption
12
+ 4. **AGENTS WRITE TO FILES** - Each agent writes results to `.coverme/agents/{ID}.json`
13
+ 5. **AGENTS RETURN ONLY "done" or "skipped"** - Never return findings in response
30
14
 
31
15
  ---
32
16
 
33
- ## PHASE 1: DISCOVERY & CONTEXT
34
-
35
- ### Step 1: Understand the Project
17
+ ## Phase 0: Setup
36
18
 
37
19
  ```bash
38
- mkdir -p .coverme
39
-
40
- # Project structure
41
- ls -la
42
- find . -maxdepth 2 -type d -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" 2>/dev/null | head -40
43
-
44
- # Count files
45
- find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.tsx" -o -name "*.py" -o -name "*.go" \) -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | wc -l
46
-
47
- # Tech stack
48
- cat package.json 2>/dev/null | head -50
49
- cat requirements.txt 2>/dev/null | head -30
50
- cat go.mod 2>/dev/null | head -30
20
+ mkdir -p .coverme/agents
21
+ rm -f .coverme/agents/*.json 2>/dev/null
51
22
  ```
52
23
 
53
- ### Step 2: Map Critical Assets
54
-
24
+ Get project stats:
55
25
  ```bash
56
- # Authentication & Authorization
57
- find . -type f \( -name "*auth*" -o -name "*session*" -o -name "*jwt*" -o -name "*login*" -o -name "*oauth*" \) -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -20
26
+ FILES=$(find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.py" -o -name "*.go" \) -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" 2>/dev/null | wc -l | tr -d ' ')
27
+ LINES=$(find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.py" \) -not -path "*/node_modules/*" -not -path "*/dist/*" 2>/dev/null | head -50 | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}')
28
+ echo "Files: $FILES, Lines: ~$LINES"
29
+ ```
58
30
 
59
- # API Routes & Controllers
60
- find . -type f \( -name "*route*" -o -name "*controller*" -o -name "*api*" -o -name "*endpoint*" -o -name "*handler*" \) -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -20
31
+ ---
61
32
 
62
- # Database & Data Access
63
- find . -type f \( -name "*model*" -o -name "*repository*" -o -name "*db*" -o -name "*database*" -o -name "*query*" \) -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -20
33
+ ## Phase 1: Launch 33 Agents (parallel, background)
64
34
 
65
- # Security Middleware
66
- find . -type f \( -name "*middleware*" -o -name "*guard*" -o -name "*interceptor*" -o -name "*validator*" \) -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -15
35
+ **CRITICAL**: Each agent MUST:
36
+ 1. Scan the codebase for its specific issues
37
+ 2. Write findings to `.coverme/agents/{PREFIX}.json`
38
+ 3. Return ONLY the word "done" or "skipped" - NOTHING ELSE
67
39
 
68
- # Config, Secrets, Environment
69
- find . -type f \( -name "*.env*" -o -name "*secret*" -o -name "*config*" -o -name "*credential*" -o -name "*key*" \) -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -20
40
+ Launch ALL with `run_in_background: true`:
70
41
 
71
- # Infrastructure & Deployment
72
- find . -type f \( -name "Dockerfile*" -o -name "docker-compose*" -o -name "*.yaml" -o -name "*.yml" -o -name "*helm*" \) -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -25
42
+ ### Agent 1: SEC - Security Core
73
43
  ```
74
-
75
- ### Step 3: Check for Previous Scan
76
-
77
- ```bash
78
- cat .coverme/scan.json 2>/dev/null | head -100 || echo "NO_PREVIOUS_SCAN"
44
+ Scan for: SQL injection, XSS, command injection, SSTI, hardcoded secrets, weak crypto.
45
+ Write to .coverme/agents/SEC.json:
46
+ [{"id":"SEC-001","title":"...","severity":"critical|high|medium|low","file":"...","line":N,"description":"...","recommendation":"..."}]
47
+ Return ONLY: "done" or "skipped"
79
48
  ```
80
49
 
81
- ---
82
-
83
- ## PHASE 2: DEEP ANALYSIS
84
-
85
- **Read the critical files you found.** For each category, actively search for issues:
86
-
87
- ### 1. SECURITY ISSUES
88
-
89
- #### 1.1 Injection Attacks
90
- - **SQL Injection**: String concatenation in queries, template literals with user input
91
- ```bash
92
- grep -r "query.*\`.*\$\{" --include="*.ts" --include="*.js" src/
93
- grep -r "execute.*+.*req\." --include="*.ts" src/
94
- ```
95
- - **NoSQL Injection**: Unvalidated MongoDB queries, Redis commands with user input
96
- - **Command Injection**: User input in exec(), spawn(), system calls
97
- ```bash
98
- grep -r "exec\(.*req\." --include="*.ts" --include="*.js" src/
99
- grep -r "spawn.*\`.*\$\{" --include="*.ts" src/
100
- ```
101
- **CRITICAL**: Config files are NOT safe! Check if model names, paths, or commands from config files are validated
102
- - **Path Traversal**: User input in file paths, missing path normalization
103
- - **SSRF**: User-controlled URLs, unvalidated webhook endpoints
104
- - **Template Injection**: Server-side template rendering with user input
105
- - **XSS**: dangerouslySetInnerHTML, innerHTML, eval() with user data
106
-
107
- #### 1.2 Authentication & Session Management
108
- - **Hardcoded Credentials**: Check ENTIRE git history!
109
- ```bash
110
- # Check if secrets are tracked
111
- git ls-files | grep -E "secret|credential|\.env$"
112
-
113
- # Check git HISTORY (even if removed now!)
114
- git log --all --full-history -- "**/secrets*" "**/credentials*" "**/*.env"
115
- git log --all -p -S "AWS_SECRET" --source --all | head -100
116
- ```
117
- - **JWT Vulnerabilities**: 'none' algorithm accepted, weak secrets, missing validation
118
- ```bash
119
- grep -r "algorithm.*none" --include="*.ts" --include="*.js" src/
120
- grep -r "jwt.verify.*algorithm" --include="*.ts" src/
121
- ```
122
- - **Session Fixation**: Session ID not regenerated after login
123
- - **Weak Password Storage**: MD5, SHA1, plaintext passwords
124
- - **Missing Rate Limiting**: No protection on auth endpoints
125
- - **OAuth Misconfiguration**: Insecure redirect_uri, state parameter issues
126
-
127
- #### 1.3 Authorization Issues
128
- - **IDOR** (Insecure Direct Object References): User can access others' data
129
- ```bash
130
- # Look for direct ID usage without auth check
131
- grep -r "findById.*req\.params" --include="*.ts" --include="*.js" src/
132
- ```
133
- - **Missing Authorization Checks**: Endpoints accessible without proper roles
134
- - **Privilege Escalation**: Paths to gain higher privileges
135
-
136
- #### 1.4 Cryptography
137
- - **Weak Algorithms**: MD5, SHA1 for passwords, DES, RC4
138
- ```bash
139
- grep -r "createHash.*md5\|createHash.*sha1" --include="*.ts" --include="*.js" src/
140
- ```
141
- - **Hardcoded Keys**: Encryption keys in code
142
- - **Weak Random**: Math.random() for security tokens
143
- - **ECB Mode**: Insecure block cipher mode
144
-
145
- #### 1.5 Sensitive Data Exposure
146
- - **API Keys in Code**: Check git history!
147
- - **Secrets in Logs**: Password, tokens logged
148
- ```bash
149
- grep -r "console.log.*password\|logger.*token" --include="*.ts" src/
150
- ```
151
- - **Error Details Leaked**: Stack traces, internal paths in responses
152
- - **PII in URLs**: Personal data in query strings
153
-
154
- #### 1.6 Security Misconfiguration
155
- - **Debug Mode in Production**: Debug flags, verbose errors
156
- - **Default Credentials**: Unchanged defaults
157
- - **Missing Security Headers**: CSP, HSTS, X-Frame-Options
158
- ```bash
159
- grep -r "helmet\(\)" --include="*.ts" --include="*.js" src/
160
- # If helmet() has no config, report as MEDIUM
161
- ```
162
- - **CORS Misconfiguration**: origin: '*' or reflecting any origin
163
- ```bash
164
- grep -r "Access-Control-Allow-Origin.*\*\|Access-Control-Allow-Origin.*req\.headers\.origin" --include="*.ts" src/
165
- ```
166
-
167
- #### 1.7 Race Conditions & Business Logic
168
- - **TOCTOU** (Time-of-check Time-of-use): Non-atomic check-then-act
169
- - **Double Spend**: Credits/tokens deducted after use instead of before
170
- - **Quota Bypass**: Race conditions in rate limiting
171
- - **Workflow Bypass**: Steps can be skipped
172
-
173
- ### 2. QUALITY ISSUES (CRITICAL!)
174
-
175
- #### 2.1 Silent Failures - **YOUR TOP PRIORITY**
176
-
177
- Silent failures are **CRITICAL** because they hide production bugs. Search aggressively:
178
-
179
- **Pattern 1: Empty catch blocks**
180
- ```bash
181
- grep -r "catch.*{[\s]*}" --include="*.ts" --include="*.js" src/
182
- grep -r "catch.*{\s*//.*\s*}" --include="*.ts" src/
50
+ ### Agent 2: AUTH - Authentication
183
51
  ```
184
-
185
- **Pattern 2: Catch with only console.log**
186
- ```bash
187
- grep -r "catch.*{[\s]*console\." --include="*.ts" --include="*.js" src/
52
+ Scan for: JWT issues, session problems, OAuth flaws, weak passwords, missing MFA.
53
+ Write to .coverme/agents/AUTH.json
54
+ Return ONLY: "done" or "skipped"
188
55
  ```
189
56
 
190
- **Pattern 3: Silent fallbacks**
191
- ```bash
192
- grep -r "catch.*return \[\]" --include="*.ts" --include="*.js" src/
193
- grep -r "catch.*return \{\}" --include="*.ts" src/
194
- grep -r "catch.*return null" --include="*.ts" src/
195
- grep -r "catch.*return ''" --include="*.ts" src/
57
+ ### Agent 3: API - API Security
196
58
  ```
197
-
198
- **Pattern 4: .catch() with no action**
199
- ```bash
200
- grep -r "\.catch\(\s*\(\)\s*=>" --include="*.ts" --include="*.js" src/
201
- grep -r "\.catch\(console\." --include="*.ts" src/
59
+ Scan for: CORS issues, rate limiting, input validation, mass assignment, GraphQL issues.
60
+ Write to .coverme/agents/API.json
61
+ Return ONLY: "done" or "skipped"
202
62
  ```
203
63
 
204
- **Examples**:
205
- ```javascript
206
- // CRITICAL - payment error hidden!
207
- try {
208
- await chargeCard(amount);
209
- } catch (e) {
210
- console.error(e); // Logs but continues to "success" response!
211
- }
212
- res.json({ success: true }); // Customer charged $0!
213
-
214
- // CRITICAL - authentication bypass
215
- try {
216
- const user = await authenticate(token);
217
- } catch {
218
- // Silent! Attacker can proceed unauthenticated
219
- }
220
-
221
- // CRITICAL - data corruption
222
- const data = parseData() || []; // Parse error becomes empty array!
64
+ ### Agent 4: INFRA - Infrastructure
223
65
  ```
224
-
225
- #### 2.2 Dead Code Detection
226
-
227
- **Strategy**: Build mental call graph, find orphans
228
-
229
- ```bash
230
- # Find all exports
231
- grep -r "export " --include="*.ts" --include="*.js" src/ | cut -d: -f1 | sort -u
232
-
233
- # For suspicious files, verify they're imported
234
- grep -r "import.*from.*filename" --include="*.ts" --include="*.js" src/
66
+ Scan for: Docker issues, K8s misconfig, CI/CD secrets, cloud misconfig.
67
+ Write to .coverme/agents/INFRA.json
68
+ Return ONLY: "done" or "skipped"
235
69
  ```
236
70
 
237
- **Check**:
238
- - Functions with 0 callers (trace usage)
239
- - Files never imported
240
- - React components not in any route
241
- - API endpoints with no frontend calls
242
- - Event handlers for events never emitted
243
- - Code behind `if (false)` or `if (0)`
244
- - Feature flags always false
71
+ ### Agent 5: DATA - Data & Privacy
72
+ ```
73
+ Scan for: PII exposure, GDPR issues, unencrypted data.
74
+ Write to .coverme/agents/DATA.json
75
+ Return ONLY: "done" or "skipped"
76
+ ```
245
77
 
246
- #### 2.3 Code Duplication
78
+ ### Agent 5b: SECRETS - Smart Credentials Analysis
79
+ ```
80
+ Scan for credentials/secrets WITH CONTEXT ANALYSIS:
81
+
82
+ 1. **Find all potential secrets**: API keys, tokens, passwords, connection strings
83
+
84
+ 2. **For EACH secret found, analyze context**:
85
+ - Is it in .env file? Check if .env is in .gitignore
86
+ - Is it a sandbox/test/playground key? (look for prefixes: sk_test_, sandbox_, demo_, etc.)
87
+ - Is the domain a test domain? (localhost, *.test, staging.*, sandbox.*)
88
+ - Is there a .env.example suggesting this is dev setup?
89
+ - Is the secret expired? (look for expiry dates, old timestamps)
90
+ - Is it in a test file?
91
+
92
+ 3. **Rate severity based on context**:
93
+ - CRITICAL: Production secret in code, not in .env, not gitignored
94
+ - HIGH: Real credentials but only in .env (still bad if committed)
95
+ - MEDIUM: Sandbox/test credentials (may still expire and break things)
96
+ - LOW: Demo/example credentials clearly marked as such
97
+ - INFO: Placeholder values like "your-api-key-here"
98
+
99
+ 4. **Smart recommendations**:
100
+ - If sandbox key: "Sandbox key detected. Consider rotating if published to repo. Current risk: LOW"
101
+ - If .env is gitignored: "Secret properly isolated in .env. Verify .env is not committed to git history"
102
+ - If expired: "Key may be expired (created > 1 year ago). Test and rotate"
103
+
104
+ Write to .coverme/agents/SECRETS.json with:
105
+ [{"id":"SECRETS-001","title":"AWS credentials in .env","severity":"medium","file":".env","line":5,"context":{"inGitignore":true,"isPlayground":true,"hasEnvExample":true},"recommendation":"Sandbox credentials properly isolated. Consider rotation schedule."}]
106
+
107
+ Return ONLY: "done" or "skipped"
108
+ ```
247
109
 
248
- **Active search**:
249
- ```bash
250
- # Similar function names
251
- grep -r "function validate" --include="*.ts" --include="*.js" src/
252
- grep -r "function format" --include="*.ts" src/
253
- grep -r "function handle" --include="*.ts" src/
110
+ ### Agent 6: AI - AI/LLM Security
111
+ ```
112
+ FIRST: Check if AI code exists (openai, anthropic, langchain, etc.)
113
+ If no AI code: Write {"skipped":true} and return "skipped"
114
+ If AI code: Scan for prompt injection, data leakage, output validation.
115
+ Write to .coverme/agents/AI.json
116
+ Return ONLY: "done" or "skipped"
117
+ ```
254
118
 
255
- # Repeated patterns
256
- grep -r "new Date.*getMonth" --include="*.ts" src/
257
- grep -r "JSON.parse\|JSON.stringify" --include="*.ts" src/
119
+ ### Agent 7: PERF - Performance & DoS
120
+ ```
121
+ Scan for: ReDoS, N+1 queries, memory leaks, unbounded operations.
122
+ Write to .coverme/agents/PERF.json
123
+ Return ONLY: "done" or "skipped"
258
124
  ```
259
125
 
260
- Report ALL locations, not just first two!
126
+ ### Agent 8: BIZ - Business Logic
127
+ ```
128
+ Scan for: Race conditions, TOCTOU, workflow bypass, financial issues.
129
+ Write to .coverme/agents/BIZ.json
130
+ Return ONLY: "done" or "skipped"
131
+ ```
261
132
 
262
- ### 3. ARCHITECTURE ISSUES
133
+ ### Agent 9: QUAL - Code Quality
134
+ ```
135
+ Scan for: High complexity, dead code, anti-patterns.
136
+ Write to .coverme/agents/QUAL.json
137
+ Return ONLY: "done" or "skipped"
138
+ ```
263
139
 
264
- #### 3.1 Layer Violations
265
- - Controllers importing database directly (should go through services)
266
- - UI components making DB queries
267
- - Domain logic depending on infrastructure
140
+ ### Agent 9b: SILENT - Silent Failures (CRITICAL)
141
+ ```
142
+ Scan SPECIFICALLY for silent error handling patterns:
143
+
144
+ 1. **Empty catch blocks**: catch(e) {} or catch { }
145
+ 2. **Swallowed errors**: catch(e) { console.log(e) } without rethrow
146
+ 3. **Silent fallbacks**: catch(e) { return null } or catch => defaultValue
147
+ 4. **Optional chaining abuse**: data?.field?.value without fallback handling
148
+ 5. **Nullish coalescing hiding errors**: value ?? {} or value || []
149
+ 6. **Promise swallowing**: .catch(() => {}) or .catch(() => null)
150
+ 7. **Try without meaningful catch**: try { ... } catch { /* ignore */ }
151
+ 8. **Default returns in catch**: catch(e) { return [] } hiding failures
152
+ 9. **Logging without action**: catch(e) { logger.error(e); return default }
153
+ 10. **Conditional silent fails**: if (!result) return; without error
154
+
155
+ For EACH finding, rate severity:
156
+ - CRITICAL: Payment/auth/security code with silent failure
157
+ - HIGH: Data operations that silently return empty/default
158
+ - MEDIUM: API calls that swallow errors
159
+ - LOW: Non-critical utility functions
160
+
161
+ Write to .coverme/agents/SILENT.json with format:
162
+ [{"id":"SILENT-001","title":"Silent failure in payment processing","severity":"critical","file":"src/payments/charge.ts","line":45,"code":"catch(e) { return { success: false } }","impact":"Payment failures go undetected","recommendation":"Throw PaymentError and alert on-call"}]
163
+
164
+ Return ONLY: "done" or "skipped"
165
+ ```
268
166
 
269
- ```bash
270
- # Bad: Controller -> DB (should be Controller -> Service -> Repo -> DB)
271
- grep -r "import.*database\|import.*db" src/controllers/ src/routes/
272
- ```
273
-
274
- #### 3.2 Dependency Issues
275
- - Circular dependencies
276
- ```bash
277
- # Find potential circular deps
278
- find src/ -name "*.ts" -exec sh -c 'echo "=== {} ===" && grep -o "from ['\''\"]\.[^'\''\"]*" {}' \;
279
- ```
280
- - Missing dependency injection
281
- - God modules (doing everything)
282
-
283
- #### 3.3 Scalability Concerns
284
- - State stored in memory (not horizontally scalable)
285
- - Missing queue for long-running tasks
286
- - No caching strategy
287
- - Synchronous operations that should be async
288
-
289
- ### 4. PERFORMANCE ISSUES
290
-
291
- #### 4.1 Database Performance
292
- - **N+1 Queries** - THE MOST COMMON ISSUE!
293
- ```javascript
294
- // BAD: N+1
295
- const users = await User.findAll();
296
- for (const user of users) {
297
- user.posts = await Post.find({ userId: user.id }); // N queries!
298
- }
299
-
300
- // GOOD: Single query
301
- const users = await User.findAll({ include: [Post] });
302
- ```
303
- - Unbounded queries (no LIMIT)
304
- - Missing pagination
305
- - SELECT * instead of specific columns
306
- - Missing indexes
307
-
308
- #### 4.2 Memory Issues
309
- - Loading entire files into memory
310
- - Unbounded array growth
311
- - Missing streaming for large data
312
- - Memory leaks (unclosed connections, event listeners)
313
-
314
- #### 4.3 Blocking Operations
315
- - fs.readFileSync in production
316
- - Synchronous crypto operations
317
- - CPU-intensive work on main thread
318
- - Large JSON.parse
319
-
320
- #### 4.4 Network Inefficiencies
321
- - Sequential API calls that could be parallel
322
- ```javascript
323
- // BAD: Sequential
324
- const user = await fetchUser();
325
- const posts = await fetchPosts(); // Could be parallel!
326
-
327
- // GOOD: Parallel
328
- const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
329
- ```
330
- - Missing compression
331
- - No connection reuse
167
+ ### Agent 10: TEST - Testing
168
+ ```
169
+ Scan for: Missing tests on critical paths, mocked security, no E2E.
170
+ Write to .coverme/agents/TEST.json
171
+ Return ONLY: "done" or "skipped"
172
+ ```
332
173
 
333
- ---
174
+ ### Agent 11: REDIS - Cache Security
175
+ ```
176
+ FIRST: Check if Redis/cache code exists.
177
+ If not: Write {"skipped":true} and return "skipped"
178
+ If yes: Scan for dangerous commands, auth issues, race conditions.
179
+ Write to .coverme/agents/REDIS.json
180
+ Return ONLY: "done" or "skipped"
181
+ ```
334
182
 
335
- ## PHASE 3: GENERATE COMPREHENSIVE REPORT
183
+ ### Agent 12: RESIL - Resilience
184
+ ```
185
+ Scan for: Missing circuit breakers, no timeouts, no retries.
186
+ NOTE: For silent fallbacks, see Agent 9b (SILENT) which handles those specifically.
187
+ Write to .coverme/agents/RESIL.json
188
+ Return ONLY: "done" or "skipped"
189
+ ```
336
190
 
337
- Create `.coverme/scan.json` with this structure:
191
+ ### Agent 13: PII - PII Scanner
192
+ ```
193
+ Scan for: PII in logs, PII in URLs, unencrypted PII, missing GDPR controls.
194
+ Write to .coverme/agents/PII.json
195
+ Return ONLY: "done" or "skipped"
196
+ ```
338
197
 
339
- ### CRITICAL REQUIREMENT
198
+ ### Agent 14: DEAD - Dead Code
199
+ ```
200
+ Scan for: Unused functions, unused deps, commented code, TODO/FIXME.
201
+ Write to .coverme/agents/DEAD.json
202
+ Return ONLY: "done" or "skipped"
203
+ ```
340
204
 
341
- **YOU MUST CREATE DETAILED FINDINGS!**
205
+ ### Agent 15: DB - Database Security
206
+ ```
207
+ Scan for: SQL injection, NoSQL injection, missing RLS, exposed connections.
208
+ Write to .coverme/agents/DB.json
209
+ Return ONLY: "done" or "skipped"
210
+ ```
342
211
 
343
- The `findings` array is **MANDATORY** and must contain:
344
- - Full finding objects with ALL fields (not just executiveSummary.topRisks)
345
- - businessImpact with financial/reputation/legal/operational breakdown
346
- - proofOfConcept with actual exploit code
347
- - attackChain with step-by-step exploitation
348
- - quickFix vs properFix with code examples
349
- - testing instructions (manual + automated)
350
- - detection methods (commands + indicators)
351
- - estimatedEffort (human vs claudeCode with ROI)
212
+ ### Agent 16: ARCH - Architecture
213
+ ```
214
+ Scan for: Internal endpoints exposed, missing mTLS, network issues.
215
+ Write to .coverme/agents/ARCH.json
216
+ Return ONLY: "done" or "skipped"
217
+ ```
352
218
 
353
- **DO NOT** create only `executiveSummary.topRisks` - you **MUST** also create full finding objects in the `findings` array!
219
+ ### Agent 17: DESIGN - Design Decisions
220
+ ```
221
+ Find documented design decisions that might look like bugs (intentional patterns).
222
+ Write to .coverme/agents/DESIGN.json
223
+ Return ONLY: "done" or "skipped"
224
+ ```
354
225
 
355
- ### Required Fields
356
- - `agentCount`: Always `1` (unified agent)
357
- - `scanDuration`: e.g., "8m 30s" or "512s"
358
- - `filesScanned`: Total files analyzed
359
- - `linesOfCode`: Total LOC
226
+ ### Agent 18: CTX - Context Validator
227
+ ```
228
+ For critical findings from other agents, check deployment context.
229
+ Write to .coverme/agents/CTX.json
230
+ Return ONLY: "done" or "skipped"
231
+ ```
360
232
 
361
- ### Report Structure
233
+ ### Agent 19: ENC - Enclave Security
234
+ ```
235
+ FIRST: Check if enclave/TEE code exists.
236
+ If not: Write {"skipped":true} and return "skipped"
237
+ If yes: Scan for attestation issues.
238
+ Write to .coverme/agents/ENC.json
239
+ Return ONLY: "done" or "skipped"
240
+ ```
362
241
 
363
- ```json
364
- {
365
- "projectName": "project-name",
366
- "scanDate": "2026-02-18T15:00:00Z",
367
- "filesScanned": 234,
368
- "linesOfCode": 62501,
369
- "agentCount": 1,
370
- "scanDuration": "8m 30s",
371
-
372
- "projectTree": "project/\n├── src/\n│ ├── routes/\n│ ├── services/\n│ └── middleware/\n├── tests/\n└── package.json",
373
-
374
- "projectOverview": {
375
- "name": "Project Name",
376
- "type": "Backend API | Full Stack App | Microservices",
377
- "stack": ["Node.js 18", "TypeScript", "PostgreSQL", "Redis"],
378
- "purpose": "What this project does in 1-2 sentences",
379
- "architecture": "Monolith | Microservices | Serverless | Layered",
380
- "keyComponents": ["src/routes/", "src/services/", "src/middleware/"]
381
- },
382
-
383
- "executiveSummary": {
384
- "headline": "X Critical + Y High security findings, Z quality issues",
385
- "riskLevel": "CRITICAL | HIGH | MEDIUM | LOW",
386
- "overview": "Professional 2-3 sentence summary. Describe architecture → security posture → main concerns.",
387
- "topRisks": [
388
- "SQL injection in user search (src/routes/users.ts:45) - full database access",
389
- "Hardcoded AWS keys in git history (commit abc123) - account compromise",
390
- "Silent payment errors (src/services/payment.ts:89) - financial loss"
391
- ],
392
- "positives": [
393
- "Post-quantum cryptography implemented (ML-KEM-768)",
394
- "Proper password hashing with bcrypt cost 12",
395
- "Comprehensive input validation on all API endpoints"
396
- ],
397
- "recommendedActions": [
398
- {
399
- "priority": 1,
400
- "action": "Rotate AWS keys exposed in git history, move to Secrets Manager",
401
- "owner": "devops",
402
- "effort": "1-2 hours"
403
- },
404
- {
405
- "priority": 2,
406
- "action": "Fix SQL injection by using parameterized queries",
407
- "owner": "developer",
408
- "effort": "2-3 hours"
409
- }
410
- ]
411
- },
412
-
413
- "architectureOverview": {
414
- "components": [
415
- {
416
- "name": "Frontend (Next.js)",
417
- "type": "client",
418
- "description": "React application with client-side encryption",
419
- "files": ["frontend/app/", "frontend/components/"],
420
- "trustLevel": "untrusted"
421
- },
422
- {
423
- "name": "API Gateway (Express)",
424
- "type": "service",
425
- "description": "Authentication, rate limiting, payload routing",
426
- "files": ["backend/src/routes/", "backend/src/middleware/"],
427
- "trustLevel": "semi-trusted"
428
- },
429
- {
430
- "name": "Database (PostgreSQL)",
431
- "type": "database",
432
- "description": "User data, sessions, application state",
433
- "files": ["backend/src/models/"],
434
- "trustLevel": "trusted"
435
- }
436
- ],
437
- "trustBoundaries": [
438
- {
439
- "name": "TB1: Internet → Frontend",
440
- "from": "Internet (Attackers)",
441
- "to": "Browser Application",
442
- "protocol": "HTTPS",
443
- "description": "Untrusted user input enters system",
444
- "type": "external"
445
- },
446
- {
447
- "name": "TB2: Frontend → API Gateway",
448
- "from": "Browser",
449
- "to": "Backend API",
450
- "protocol": "HTTPS + JWT",
451
- "description": "Authentication boundary - JWT validation required",
452
- "type": "external"
453
- },
454
- {
455
- "name": "TB3: API Gateway → Services",
456
- "from": "API Gateway",
457
- "to": "Business Logic",
458
- "description": "Trusted internal boundary - service layer",
459
- "type": "internal"
460
- }
461
- ],
462
- "criticalAssets": [
463
- {
464
- "name": "User Passwords",
465
- "type": "credential",
466
- "storage": "Database (bcrypt hashed)",
467
- "description": "User authentication credentials - never stored plaintext",
468
- "protection": "bcrypt cost 12"
469
- },
470
- {
471
- "name": "JWT Signing Secret",
472
- "type": "key",
473
- "storage": "Environment variable JWT_SECRET",
474
- "description": "Used to sign authentication tokens",
475
- "protection": "Environment variable, rotated monthly"
476
- },
477
- {
478
- "name": "Database Connection String",
479
- "type": "credential",
480
- "storage": "Environment variable DATABASE_URL",
481
- "description": "PostgreSQL connection with admin privileges",
482
- "protection": "Environment variable, encrypted at rest"
483
- },
484
- {
485
- "name": "API Keys (Stripe, AWS)",
486
- "type": "credential",
487
- "storage": "Secrets Manager / .env",
488
- "description": "Third-party service authentication",
489
- "protection": "AWS Secrets Manager or gitignored .env"
490
- }
491
- ],
492
- "entryPoints": [
493
- {
494
- "path": "POST /api/auth/login",
495
- "authentication": "none",
496
- "description": "User authentication endpoint - rate limited",
497
- "riskLevel": "high"
498
- },
499
- {
500
- "path": "GET /api/users/:id",
501
- "authentication": "JWT required",
502
- "description": "User profile data - authorization check required",
503
- "riskLevel": "medium"
504
- },
505
- {
506
- "path": "POST /api/payments",
507
- "authentication": "JWT required",
508
- "description": "Payment processing - high value target",
509
- "riskLevel": "critical"
510
- }
511
- ],
512
- "dataFlows": [
513
- "Browser → HTTPS → API Gateway → JWT Validation → Service Layer → Repository → Database",
514
- "Browser → File Upload → API Gateway → Virus Scan → S3 Bucket",
515
- "API Gateway → External API (Stripe) → Payment Processing"
516
- ]
517
- },
518
-
519
- "findings": [
520
- {
521
- "id": "SEC-001",
522
- "title": "SQL Injection in User Search Endpoint",
523
- "severity": "critical",
524
- "category": "security",
525
- "file": "src/routes/users.ts",
526
- "line": 45,
527
- "endLine": 52,
528
- "code": "const query = `SELECT * FROM users WHERE name = '${req.query.name}'`;",
529
- "description": "User input from req.query.name is directly concatenated into SQL query without sanitization. An attacker can inject arbitrary SQL commands.",
530
-
531
- "impact": "Complete database compromise. Attacker can:\n1. Extract all user data including passwords\n2. Modify or delete records\n3. Execute administrative operations\n4. Potential remote code execution via database extensions",
532
-
533
- "businessImpact": {
534
- "financial": "GDPR fine: €20M or 4% of revenue. Average data breach cost: $4.35M (IBM 2023)",
535
- "reputation": "Customer trust loss: 6-12 months recovery. 65% customers leave after breach (PwC)",
536
- "legal": "Class action lawsuit risk. SEC investigation if publicly traded",
537
- "operational": "2-4 weeks incident response, forensics, customer notifications"
538
- },
539
-
540
- "realWorldExamples": [
541
- "Equifax (2017): SQL injection → 147M records stolen → $700M settlement",
542
- "TalkTalk (2015): SQL injection → 157K customers exposed → £400K fine",
543
- "Your industry: 23% of companies experienced SQL injection in 2023 (Verizon DBIR)"
544
- ],
545
-
546
- "attackChain": [
547
- {"step": 1, "action": "Send: GET /api/users?name=' OR '1'='1' --", "result": "Returns all users (authentication bypass)"},
548
- {"step": 2, "action": "Send: name=' UNION SELECT password,email FROM admins--", "result": "Extract admin credentials"},
549
- {"step": 3, "action": "Send: name='; DROP TABLE users; --", "result": "Data destruction (if permissions allow)"},
550
- {"step": 4, "action": "Send: name=' INTO OUTFILE '/var/www/shell.php'--", "result": "Remote code execution"}
551
- ],
552
-
553
- "proofOfConcept": "# Test this vulnerability:\ncurl 'https://api.example.com/users?name=%27%20OR%20%271%27%3D%271' \\\n -H 'Authorization: Bearer $TOKEN'\n\n# Expected (vulnerable): Returns all users\n# Expected (fixed): Returns 400 Bad Request",
554
-
555
- "recommendation": "Use parameterized queries:\n\n```typescript\n// ✅ SECURE - Parameterized query\nconst query = 'SELECT * FROM users WHERE name = $1';\nconst result = await db.query(query, [req.query.name]);\n```",
556
-
557
- "quickFix": {
558
- "description": "Add input validation (1 hour)",
559
- "code": "// Quick temporary fix\nconst safeName = req.query.name.replace(/[^a-zA-Z0-9 ]/g, '');\nconst query = `SELECT * FROM users WHERE name = '${safeName}'`;",
560
- "limitations": "Not foolproof - still vulnerable to advanced attacks"
561
- },
562
-
563
- "properFix": {
564
- "description": "Switch to parameterized queries + add WAF (1 day)",
565
- "code": "// Proper fix\nconst query = 'SELECT * FROM users WHERE name = $1';\nconst result = await db.query(query, [req.query.name]);",
566
- "additionalSteps": [
567
- "Add input validation middleware (Joi/Zod schema)",
568
- "Enable SQL injection protection in WAF (Cloudflare/AWS WAF)",
569
- "Add query logging for security monitoring",
570
- "Run database user with minimal privileges (not root)"
571
- ]
572
- },
573
-
574
- "testing": {
575
- "description": "How to verify the fix works",
576
- "manual": [
577
- "Test: curl 'https://api.example.com/users?name=%27%20OR%20%271%27%3D%271'",
578
- "Expected: 400 Bad Request with error message",
579
- "Test: curl 'https://api.example.com/users?name=John'",
580
- "Expected: Returns user 'John' only"
581
- ],
582
- "automated": "# Add security test\ntest('should reject SQL injection attempts', async () => {\n const response = await request(app)\n .get('/api/users?name=\\' OR \\'1\\'=\\'1')\n .expect(400);\n expect(response.body.error).toContain('Invalid input');\n});"
583
- },
584
-
585
- "detection": {
586
- "description": "How to check if already exploited",
587
- "commands": [
588
- "# Check access logs for SQL injection patterns",
589
- "grep -E \"(UNION|SELECT|INSERT|DROP|--|;)\" /var/log/nginx/access.log",
590
- "# Check database audit logs",
591
- "SELECT * FROM pg_stat_statements WHERE query LIKE '%UNION%' OR query LIKE '%--';"
592
- ],
593
- "indicators": [
594
- "Unusual SQL errors in application logs",
595
- "Multiple failed queries from same IP",
596
- "Database queries with suspicious patterns (UNION, --, ;)",
597
- "Unexpected spike in database CPU usage"
598
- ]
599
- },
600
-
601
- "dread": {
602
- "damage": 10,
603
- "reproducibility": 10,
604
- "exploitability": 9,
605
- "affectedUsers": 10,
606
- "discoverability": 8,
607
- "score": 9.4
608
- },
609
-
610
- "cwe": "CWE-89",
611
- "owasp": "A03:2021-Injection",
612
- "cvss": "9.8 (Critical)",
613
-
614
- "references": [
615
- "https://owasp.org/www-community/attacks/SQL_Injection",
616
- "https://cwe.mitre.org/data/definitions/89.html",
617
- "https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html"
618
- ],
619
-
620
- "evidence": [
621
- "Input source: req.query.name (line 44) - no validation",
622
- "Sink: db.query() (line 45) - string concatenation",
623
- "No sanitization between source and sink",
624
- "Endpoint is publicly accessible",
625
- "Database user has full privileges (checked schema)"
626
- ],
627
-
628
- "fixOwner": "developer",
629
- "estimatedEffort": {
630
- "human": "4-6 hours (research parameterized queries, update all SQL calls, write tests, deploy)",
631
- "claudeCode": "15-20 minutes (finds all SQL concatenations, generates parameterized versions, writes tests)",
632
- "roi": "18x faster with Claude Code"
633
- },
634
- "priority": 1
635
- },
636
- {
637
- "id": "QUAL-001",
638
- "title": "Silent Payment Error Handling - Financial Loss Risk",
639
- "severity": "critical",
640
- "category": "quality",
641
- "file": "src/services/paymentService.ts",
642
- "line": 89,
643
- "endLine": 95,
644
- "code": "try {\n await stripe.charges.create(charge);\n} catch (err) {\n console.error('Payment error:', err);\n}\nreturn { success: true };",
645
-
646
- "description": "Payment errors are caught and logged but execution continues. The function returns success:true even when payment fails. Customer receives product without paying. This is a SILENT FAILURE - the most dangerous type of bug.",
647
-
648
- "impact": "Direct financial loss. Orders are fulfilled without payment. Customer sees 'success' and receives product/service for $0.",
649
-
650
- "businessImpact": {
651
- "financial": "Stripe reports 3% payment failure rate. At 1000 orders/month × $50 avg = $1,500/month revenue loss = $18K/year",
652
- "reputation": "Accounting discovers revenue discrepancy → loss of investor confidence",
653
- "legal": "Incorrect financial reporting → potential audit/compliance issues",
654
- "operational": "Manual reconciliation required to find unpaid orders"
655
- },
656
-
657
- "realWorldExamples": [
658
- "Knight Capital (2012): Silent error handling → $440M loss in 45 minutes",
659
- "Your scenario: Payment fails, user gets premium subscription free. Stripe dispute shows no payment.",
660
- "Common pattern: 30% of payment bugs are silent failures (Sentry data 2023)"
661
- ],
662
-
663
- "attackChain": [
664
- {"step": 1, "action": "User submits order for $100 product", "result": "Order processing begins"},
665
- {"step": 2, "action": "Stripe payment fails (network error, card declined, etc)", "result": "Exception thrown, caught silently"},
666
- {"step": 3, "action": "Code continues, returns {success: true}", "result": "User sees success message"},
667
- {"step": 4, "action": "Fulfillment system processes 'successful' order", "result": "Product shipped/service activated for $0"}
668
- ],
669
-
670
- "proofOfConcept": "// Reproduce the bug:\n// 1. Set STRIPE_TEST_MODE=true\n// 2. Use test card 4000000000000341 (card declined)\n// 3. Submit order\n// 4. Observe: Payment fails but order succeeds\n\nawait fetch('/api/orders', {\n method: 'POST',\n body: JSON.stringify({\n cardNumber: '4000000000000341', // Test card that declines\n amount: 100\n })\n});\n// Result: {success: true} even though payment failed",
671
-
672
- "recommendation": "Rethrow error or return failure:\n\n```typescript\n// ✅ PROPER ERROR HANDLING\ntry {\n const charge = await stripe.charges.create(chargeData);\n await db.orders.update(orderId, { status: 'paid', chargeId: charge.id });\n return { success: true, chargeId: charge.id };\n} catch (err) {\n // Log with context\n logger.error('Payment failed', { \n orderId, \n amount, \n error: err.message,\n userId \n });\n \n // Update order status\n await db.orders.update(orderId, { status: 'payment_failed' });\n \n // Return failure to caller\n throw new PaymentError('Payment processing failed', { cause: err });\n}\n```",
673
-
674
- "quickFix": {
675
- "description": "Add return statement in catch (30 minutes)",
676
- "code": "try {\n await stripe.charges.create(charge);\n} catch (err) {\n console.error('Payment error:', err);\n return { success: false, error: 'Payment failed' }; // FIX: Return failure\n}\nreturn { success: true };",
677
- "limitations": "Still loses error details, no proper logging, no order status update"
678
- },
679
-
680
- "properFix": {
681
- "description": "Comprehensive error handling with transaction rollback (4 hours)",
682
- "code": "async function processPayment(orderId, chargeData) {\n const transaction = await db.transaction();\n \n try {\n // 1. Charge the card\n const charge = await stripe.charges.create(chargeData);\n \n // 2. Update order in transaction\n await transaction.orders.update(orderId, { \n status: 'paid',\n chargeId: charge.id,\n paidAt: new Date()\n });\n \n await transaction.commit();\n \n return { success: true, chargeId: charge.id };\n \n } catch (err) {\n // Rollback database changes\n await transaction.rollback();\n \n // Structured logging\n logger.error('Payment failed', {\n orderId,\n userId: chargeData.customer,\n amount: chargeData.amount,\n currency: chargeData.currency,\n errorType: err.type,\n errorMessage: err.message,\n stripeRequestId: err.requestId\n });\n \n // Update order status\n await db.orders.update(orderId, { \n status: 'payment_failed',\n failureReason: err.message \n });\n \n // Throw typed error\n throw new PaymentError('Payment processing failed', { \n cause: err,\n orderId,\n retryable: err.type === 'card_error'\n });\n }\n}",
683
- "additionalSteps": [
684
- "Add payment monitoring/alerting (e.g., Sentry, DataDog)",
685
- "Implement dead letter queue for failed payments",
686
- "Add manual reconciliation job (daily check: orders vs Stripe charges)",
687
- "Create customer notification for payment failures"
688
- ]
689
- },
690
-
691
- "testing": {
692
- "description": "Test all error scenarios",
693
- "manual": [
694
- "Test 1: Use Stripe test card 4000000000000341 (card declined) → should return error",
695
- "Test 2: Disable internet → should handle network error",
696
- "Test 3: Invalid API key → should catch auth error",
697
- "Test 4: Check database: failed orders should have status='payment_failed'"
698
- ],
699
- "automated": "describe('Payment error handling', () => {\n it('should fail order when payment declines', async () => {\n // Mock Stripe to throw error\n stripe.charges.create.mockRejectedValue(\n new Error('card_declined')\n );\n \n await expect(\n processPayment(orderId, chargeData)\n ).rejects.toThrow(PaymentError);\n \n // Verify order status updated\n const order = await db.orders.find(orderId);\n expect(order.status).toBe('payment_failed');\n });\n \n it('should not fulfill order on payment failure', async () => {\n stripe.charges.create.mockRejectedValue(new Error());\n \n try {\n await processPayment(orderId, chargeData);\n } catch (err) {\n // Expected\n }\n \n const order = await db.orders.find(orderId);\n expect(order.fulfilledAt).toBeNull();\n });\n});"
700
- },
701
-
702
- "detection": {
703
- "description": "Find orders that were fulfilled without payment",
704
- "commands": [
705
- "# Find orders with status='success' but no Stripe charge",
706
- "SELECT * FROM orders WHERE status = 'completed' AND charge_id IS NULL;",
707
- "",
708
- "# Check logs for silent payment errors",
709
- "grep 'Payment error' /var/log/app.log | grep -v 'PaymentError thrown'",
710
- "",
711
- "# Reconciliation: Compare orders vs Stripe charges",
712
- "node scripts/reconcile-payments.js --date 2026-02-01"
713
- ],
714
- "indicators": [
715
- "Orders table: status='completed' but charge_id is NULL",
716
- "Stripe dashboard: Fewer charges than completed orders",
717
- "Revenue mismatch: Reported revenue < Stripe deposits",
718
- "Customer support: Users report being charged $0"
719
- ]
720
- },
721
-
722
- "references": [
723
- "https://stripe.com/docs/error-handling",
724
- "https://martinfowler.com/articles/replaceThrowWithNotification.html"
725
- ],
726
-
727
- "evidence": [
728
- "catch block at line 91 only logs - no rethrow, no return false",
729
- "No return/throw in catch block",
730
- "Success returned at line 95 regardless of payment result",
731
- "No database rollback on payment failure",
732
- "Checked Stripe webhook logs: confirms payment failures happen but are ignored"
733
- ],
734
-
735
- "fixOwner": "developer",
736
- "estimatedEffort": {
737
- "human": "4-6 hours (identify all error paths, add transaction handling, write error tests, manual reconciliation check)",
738
- "claudeCode": "25-30 minutes (finds all try-catch blocks, adds proper error handling, generates test cases)",
739
- "roi": "12x faster with Claude Code"
740
- },
741
- "priority": 1
742
- }
743
- ],
744
-
745
- "qualityReview": {
746
- "deleteItems": [
747
- {
748
- "file": "src/legacy/oldAuth.ts",
749
- "lines": 450,
750
- "description": "Entire file unused - no imports found in codebase"
751
- }
752
- ],
753
- "mergeItems": [
754
- {
755
- "file": "src/utils/dateFormat.ts + src/helpers/formatDate.ts",
756
- "description": "Identical date formatting logic in 2 files (180 lines total)"
757
- }
758
- ],
759
- "simplifyItems": [
760
- {
761
- "file": "src/services/userService.ts",
762
- "description": "1000+ line function should be split into smaller functions"
763
- }
764
- ],
765
- "totalLinesRemovable": 630,
766
- "percentageOfCodebase": 1.0
767
- },
768
-
769
- "positiveObservations": [
770
- {
771
- "title": "Proper Password Hashing",
772
- "description": "Uses bcrypt with cost factor 12 in src/auth/password.ts:23. Passwords are never stored in plaintext."
773
- },
774
- {
775
- "title": "Rate Limiting Implemented",
776
- "description": "Express-rate-limit configured on all auth endpoints (src/middleware/rateLimit.ts:15) - prevents brute force."
777
- },
778
- {
779
- "title": "Comprehensive Input Validation",
780
- "description": "Joi schemas defined for all API inputs (src/validators/) - prevents injection attacks."
781
- }
782
- ],
783
-
784
- "summary": {
785
- "critical": 2,
786
- "high": 5,
787
- "medium": 8,
788
- "low": 3,
789
- "total": 18
790
- }
791
- }
242
+ ### Agent 20: EXEC - Executive Summary
243
+ ```
244
+ After scanning, generate executive summary with top risks and positives.
245
+ Write to .coverme/agents/EXEC.json
246
+ Return ONLY: "done"
792
247
  ```
793
248
 
794
- ### DREAD Scoring (REQUIRED for critical/high)
249
+ ### Agent 21: DUP - Duplicate Finder
250
+ ```
251
+ Find existing solutions in codebase that could fix other findings.
252
+ Write to .coverme/agents/DUP.json
253
+ Return ONLY: "done" or "skipped"
254
+ ```
795
255
 
796
- | Score | Meaning |
797
- |-------|---------|
798
- | 10 | Worst case |
799
- | 7-9 | Severe |
800
- | 4-6 | Moderate |
801
- | 1-3 | Minor |
256
+ ### Agent 22: POSITIVE - Good Patterns
257
+ ```
258
+ Find positive security patterns and good practices in the codebase.
259
+ Write to .coverme/agents/POSITIVE.json
260
+ Return ONLY: "done"
261
+ ```
802
262
 
803
- - **Damage**: Impact if exploited
804
- - **Reproducibility**: How consistently exploitable
805
- - **Exploitability**: Skill level needed
806
- - **Affected Users**: Scope of impact
807
- - **Discoverability**: How easy to find
808
- - **Score**: Average of all five
263
+ ---
809
264
 
810
- ### Attack Chain (REQUIRED for critical/high)
265
+ ## AI-Generated Code Detection Agents (23-31)
811
266
 
812
- Show realistic, step-by-step exploitation:
267
+ These agents specifically target vulnerabilities common in AI-generated code.
813
268
 
814
- ```json
815
- [
816
- {"step": 1, "action": "Concrete attacker action", "result": "What happens"},
817
- {"step": 2, "action": "Next action with actual payload", "result": "Escalation"},
818
- {"step": 3, "action": "Final action", "result": "Full compromise"}
819
- ]
269
+ ### Agent 23: ASSUME - AI Assumptions (CRITICAL)
270
+ ```
271
+ AI code makes dangerous implicit assumptions. Scan for:
272
+
273
+ 1. **Non-null assertions**: data!.field, user!.id (TypeScript !)
274
+ 2. **Unsafe casts**: as any, as unknown, type assertions without validation
275
+ 3. **Unvalidated JSON**: JSON.parse() without try/catch or schema validation
276
+ 4. **Trusted input**: req.body used directly without validation (zod, joi, yup)
277
+ 5. **Array assumptions**: arr[0] without checking length, arr.map without null check
278
+ 6. **Object assumptions**: obj.field without checking obj exists
279
+ 7. **Destructuring without defaults**: const {a, b} = data (what if data is null?)
280
+ 8. **Assumed authentication**: Routes using req.user without auth middleware
281
+ 9. **Assumed types**: parseInt(x) without NaN check, Number(x) used blindly
282
+ 10. **Assumed existence**: await db.findOne() used without null check
283
+
284
+ Severity:
285
+ - CRITICAL: Auth/payment code with assumptions
286
+ - HIGH: Data mutation with unchecked input
287
+ - MEDIUM: API responses with assumptions
288
+ - LOW: Internal utility code
289
+
290
+ Write to .coverme/agents/ASSUME.json:
291
+ [{"id":"ASSUME-001","title":"Unvalidated req.body in user update","severity":"high","file":"src/api/users.ts","line":45,"code":"const { email, name } = req.body","assumption":"Input is valid object with email and name","exploit":"Send malformed JSON or missing fields","recommendation":"Add zod schema validation"}]
292
+
293
+ Return ONLY: "done" or "skipped"
820
294
  ```
821
295
 
822
- ---
296
+ ### Agent 24: TRUST - Trust Boundary Violations (CRITICAL)
297
+ ```
298
+ AI rarely identifies trust boundaries. Scan for:
299
+
300
+ 1. **Missing auth middleware**: app.post/get/put/delete without auth check
301
+ 2. **Admin routes unprotected**: /admin/*, /internal/* without role check
302
+ 3. **Internal service exposure**: Internal APIs accessible from public routes
303
+ 4. **Header trust**: Using x-user-id, x-role from headers without verification
304
+ 5. **Forwarded input**: User input passed to internal services without sanitization
305
+ 6. **Missing role checks**: Actions performed without checking user.role
306
+ 7. **Tenant isolation missing**: Multi-tenant data accessed without tenant filter
307
+ 8. **Service-to-service trust**: Internal calls without mTLS or API keys
308
+ 9. **Webhook endpoints**: /webhook/* without signature verification
309
+ 10. **File upload paths**: User-controlled paths without sanitization
310
+
311
+ For each finding, identify:
312
+ - What trust boundary is violated
313
+ - Who can exploit it (anonymous, authenticated, admin)
314
+ - What they can access/do
315
+
316
+ Write to .coverme/agents/TRUST.json:
317
+ [{"id":"TRUST-001","title":"Admin endpoint without role check","severity":"critical","file":"src/routes/admin.ts","line":12,"code":"app.post('/admin/delete-user', async (req,res) => { await deleteUser(req.body.id) })","boundary":"Admin actions accessible to any authenticated user","exploit":"Any logged-in user can delete other users","recommendation":"Add requireRole('admin') middleware"}]
318
+
319
+ Return ONLY: "done" or "skipped"
320
+ ```
823
321
 
824
- ## PHASE 4: VALIDATE & GENERATE REPORT
322
+ ### Agent 25: PARTIAL - Partial Security Implementation
323
+ ```
324
+ AI implements "half security" - looks secure but isn't. Scan for:
325
+
326
+ 1. **bcrypt without proper cost**: bcrypt.hash(pwd, 1) or no salt rounds
327
+ 2. **JWT without expiration**: jwt.sign() without expiresIn
328
+ 3. **JWT without verification**: jwt.decode() instead of jwt.verify()
329
+ 4. **Rate limiting without IP**: Rate limit by user but not IP (pre-auth attacks)
330
+ 5. **CSRF token generated but not checked**: Token created but middleware missing
331
+ 6. **CORS with wildcard**: Access-Control-Allow-Origin: * with credentials
332
+ 7. **Helmet without CSP**: Using helmet() but no Content-Security-Policy
333
+ 8. **HTTPS redirect missing**: No force-ssl or redirect middleware
334
+ 9. **Cookie without flags**: Missing httpOnly, secure, sameSite
335
+ 10. **Encryption without IV**: AES without initialization vector
336
+ 11. **Password validation weak**: Only length check, no complexity
337
+ 12. **Session without rotation**: No session regeneration on auth change
338
+
339
+ Write to .coverme/agents/PARTIAL.json:
340
+ [{"id":"PARTIAL-001","title":"JWT signed but never expires","severity":"high","file":"src/auth/token.ts","line":23,"code":"jwt.sign(payload, secret)","issue":"Token has no expiration","impact":"Stolen tokens valid forever","recommendation":"Add expiresIn: '1h' or similar"}]
341
+
342
+ Return ONLY: "done" or "skipped"
343
+ ```
825
344
 
826
- ### Step 1: Validate JSON
345
+ ### Agent 26: GENERR - Over-Generalized Errors
346
+ ```
347
+ AI hides errors behind generic messages. Scan for:
348
+
349
+ 1. **Generic catch-all**: catch(e) { return { error: "Something went wrong" } }
350
+ 2. **Lost error context**: catch(e) { throw new Error("Failed") } - original e lost
351
+ 3. **Boolean error returns**: return false instead of throwing
352
+ 4. **Silent status codes**: return res.status(500) without logging
353
+ 5. **Error message swallowing**: catch(e) { console.log("error") } - e not logged
354
+ 6. **Missing error types**: All errors thrown as generic Error, not typed
355
+ 7. **No error codes**: Errors without codes for client handling
356
+ 8. **Audit trail gaps**: Security errors not logged differently
357
+ 9. **User-facing stack traces**: In dev mode, stack traces leak to client
358
+ 10. **Missing error boundaries**: React without ErrorBoundary, no global handler
359
+
360
+ Impact analysis:
361
+ - Security errors hidden = attacks go undetected
362
+ - Missing audit = compliance failure
363
+ - Generic errors = impossible debugging
364
+
365
+ Write to .coverme/agents/GENERR.json:
366
+ [{"id":"GENERR-001","title":"Auth failure returns generic error","severity":"high","file":"src/auth/login.ts","line":34,"code":"catch(e) { return { success: false, error: 'Login failed' } }","issue":"Cannot distinguish wrong password vs account locked vs brute force","recommendation":"Log detailed error server-side, return error code to client"}]
367
+
368
+ Return ONLY: "done" or "skipped"
369
+ ```
827
370
 
828
- ```bash
829
- python3 -m json.tool .coverme/scan.json > /dev/null && echo "JSON valid" || echo "JSON invalid - fix it!"
371
+ ### Agent 27: CLONE - Copy-Paste Vulnerabilities
372
+ ```
373
+ AI duplicates code blocks, spreading bugs. Scan for:
374
+
375
+ 1. **Near-identical functions**: Functions >80% similar in different files
376
+ 2. **Duplicated middleware**: Same auth/validation logic repeated
377
+ 3. **Copy-pasted API handlers**: Similar CRUD operations with slight changes
378
+ 4. **Repeated validation**: Same validation rules in multiple places
379
+ 5. **Duplicated error handling**: Same try/catch pattern everywhere
380
+ 6. **Config duplication**: Same config values hardcoded in multiple files
381
+ 7. **SQL query duplication**: Same queries in different files
382
+ 8. **Duplicated security checks**: Same role check logic repeated
383
+
384
+ Why this matters:
385
+ - Fix in one place, bug remains in copies
386
+ - Inconsistent behavior across duplicates
387
+ - Maintenance nightmare
388
+
389
+ Write to .coverme/agents/CLONE.json:
390
+ [{"id":"CLONE-001","title":"Auth check duplicated in 5 files","severity":"medium","files":["src/api/users.ts:12","src/api/orders.ts:8","src/api/products.ts:15"],"pattern":"if (!req.user) return res.status(401)","issue":"Auth logic duplicated, inconsistent in orders.ts","recommendation":"Extract to requireAuth middleware"}]
391
+
392
+ Return ONLY: "done" or "skipped"
830
393
  ```
831
394
 
832
- **If invalid, fix these common errors**:
833
- - Missing `]` to close arrays (especially `attackChain`)
834
- - Missing `}` to close objects
835
- - Trailing commas before `]` or `}`
836
- - Unescaped quotes in strings
395
+ ### Agent 28: HARDCODE - Hardcoded Logic Vulnerabilities
396
+ ```
397
+ AI hardcodes values that should be configurable/validated. Scan for:
398
+
399
+ 1. **Role checks with strings**: if (user.role === "admin") - role from where?
400
+ 2. **Hardcoded IDs**: if (userId === "123") or specific UUIDs
401
+ 3. **Magic numbers**: if (amount > 10000) without named constant
402
+ 4. **Hardcoded URLs**: fetch("https://api.example.com") in code
403
+ 5. **Hardcoded credentials**: Even in dev, password = "admin123"
404
+ 6. **Hardcoded feature flags**: if (process.env.NODE_ENV === "production")
405
+ 7. **Hardcoded timeouts**: setTimeout(fn, 5000) without config
406
+ 8. **Hardcoded limits**: if (items.length > 100) without constant
407
+ 9. **Hardcoded paths**: fs.readFile("/var/app/config.json")
408
+ 10. **Hardcoded emails/domains**: admin@company.com in code
409
+
410
+ Security impact:
411
+ - Role checks bypassable if role source is tainted
412
+ - IDs expose internal structure
413
+ - Can't rotate credentials without code change
414
+
415
+ Write to .coverme/agents/HARDCODE.json:
416
+ [{"id":"HARDCODE-001","title":"Admin role check trusts user-provided role","severity":"critical","file":"src/middleware/admin.ts","line":5,"code":"if (req.user.role === 'admin')","issue":"role comes from JWT claims which user might control","recommendation":"Verify role from database, not token"}]
417
+
418
+ Return ONLY: "done" or "skipped"
419
+ ```
837
420
 
838
- ### Step 2: Generate HTML
421
+ ### Agent 29: AISTYLE - AI Code Style Heuristics
422
+ ```
423
+ Identify code that shows signs of AI generation, then audit harder. Scan for:
424
+
425
+ DETECTION PATTERNS (AI-generated code often has):
426
+ 1. **Excessive comments**: // This function does X, // Check if Y
427
+ 2. **Over-engineering**: Simple task with complex abstraction
428
+ 3. **Inconsistent style**: Mixed patterns in same file
429
+ 4. **TODO/FIXME clusters**: Multiple incomplete items
430
+ 5. **Heavy use of any**: TypeScript with lots of any/unknown
431
+ 6. **console.log in production**: Debug statements left in
432
+ 7. **Default values everywhere**: value ?? defaultValue pattern
433
+ 8. **Try-catch wrapping everything**: Even simple operations
434
+ 9. **Unused imports/variables**: Dead code not cleaned up
435
+ 10. **Generic function names**: handleClick, processData, doSomething
436
+
437
+ For detected AI-style code, perform DEEPER AUDIT:
438
+ - Check all assumptions
439
+ - Verify error handling
440
+ - Look for edge cases
441
+ - Check security controls
442
+
443
+ Write to .coverme/agents/AISTYLE.json:
444
+ [{"id":"AISTYLE-001","title":"AI-generated payment handler needs audit","severity":"high","file":"src/payments/process.ts","indicators":["excessive comments","try-catch everything","multiple TODO"],"concerns":["Error handling hides failures","No idempotency key","Missing amount validation"],"recommendation":"Manual security review required"}]
445
+
446
+ Return ONLY: "done" or "skipped"
447
+ ```
839
448
 
840
- ```bash
841
- coverme report
449
+ ### Agent 30: DEPMIS - Dependency Misuse
450
+ ```
451
+ AI imports libraries but uses them incorrectly. Scan for:
452
+
453
+ 1. **crypto misuse**: createHash without proper algorithm, no HMAC for auth
454
+ 2. **JWT misuse**: jwt.decode() for auth (should be verify), algorithm confusion
455
+ 3. **bcrypt misuse**: compareSync in async code, low rounds
456
+ 4. **axios misuse**: No timeout, no abort controller, no retry
457
+ 5. **fetch misuse**: No error handling for non-2xx, no timeout
458
+ 6. **SQL client misuse**: String concatenation instead of parameterized
459
+ 7. **Redis misuse**: No auth, KEYS in production, no TTL
460
+ 8. **fs misuse**: Sync operations blocking event loop, no path sanitization
461
+ 9. **child_process misuse**: exec with user input (command injection)
462
+ 10. **path misuse**: path.join with user input without sanitization
463
+
464
+ Write to .coverme/agents/DEPMIS.json:
465
+ [{"id":"DEPMIS-001","title":"JWT decoded but not verified","severity":"critical","file":"src/auth/middleware.ts","line":18,"code":"const user = jwt.decode(token)","issue":"decode() doesn't verify signature, attacker can forge tokens","recommendation":"Use jwt.verify(token, secret) instead"}]
466
+
467
+ Return ONLY: "done" or "skipped"
842
468
  ```
843
469
 
844
- **The scan is NOT complete until HTML opens in browser!**
470
+ ### Agent 31: LOGICGAP - Logic Gaps (CRITICAL)
471
+ ```
472
+ AI creates early returns without proper handling. Scan for:
473
+
474
+ 1. **Silent returns**: if (!user) return; - no log, no error, no audit
475
+ 2. **Missing else**: if (condition) { action } with no else handling
476
+ 3. **Incomplete state machines**: Enum/status with unhandled cases
477
+ 4. **Missing default**: switch without default case
478
+ 5. **Null returns**: return null without caller handling
479
+ 6. **Incomplete cleanup**: Resource opened but not closed on error path
480
+ 7. **Transaction gaps**: DB operations without proper rollback
481
+ 8. **Missing finally**: try/catch without finally for cleanup
482
+ 9. **Event handler gaps**: addEventListener without removeEventListener
483
+ 10. **Incomplete validation**: Some fields validated, others not
484
+
485
+ For each gap, analyze:
486
+ - What happens when the gap is hit
487
+ - Can attacker trigger the gap
488
+ - What's the impact
489
+
490
+ Write to .coverme/agents/LOGICGAP.json:
491
+ [{"id":"LOGICGAP-001","title":"Silent return on missing user","severity":"high","file":"src/api/profile.ts","line":23,"code":"if (!user) return","issue":"No logging, no 404 response, client hangs","exploit":"Probe for valid user IDs by timing differences","recommendation":"return res.status(404).json({error: 'Not found'}) and log attempt"}]
492
+
493
+ Return ONLY: "done" or "skipped"
494
+ ```
845
495
 
846
496
  ---
847
497
 
848
- ## QUALITY CHECKLIST
849
-
850
- Before finishing:
498
+ ## Phase 2: Wait for Agents
851
499
 
852
- - [ ] Read actual code files, not just names
853
- - [ ] Every critical/high finding has DREAD score
854
- - [ ] Every critical/high finding has attack chain
855
- - [ ] Searched for silent failures (empty catch, console.log only)
856
- - [ ] Checked git history for hardcoded secrets
857
- - [ ] Looked for N+1 queries in database code
858
- - [ ] Verified dead code claims (really not used?)
859
- - [ ] Found code duplications (listed ALL locations)
860
- - [ ] Executive summary is professional and specific
861
- - [ ] Architecture overview describes trust boundaries
862
- - [ ] Positive observations have specific evidence
863
- - [ ] `coverme report` generated HTML successfully
500
+ Wait for ALL background agents using `AgentOutputTool`.
501
+ Each should return only "done" or "skipped".
864
502
 
865
503
  ---
866
504
 
867
- ## EXAMPLES
505
+ ## Phase 2.5: Adversarial Review (CRITICAL)
868
506
 
869
- ### Excellent Finding (Do This!)
507
+ After all agents complete, run ONE final agent with this mindset:
870
508
 
871
- ```json
509
+ ### Agent 32: ADVERSARIAL - Systemic Weakness Review
510
+ ```
511
+ IMPORTANT: This agent runs AFTER reading all other agent findings.
512
+
513
+ ASSUME: This entire codebase was written by a junior developer
514
+ under deadline pressure using AI autocomplete.
515
+
516
+ Your mission: Find SYSTEMIC weaknesses, not just individual bugs.
517
+
518
+ 1. **Pattern Analysis**:
519
+ - What security controls are MISSING across the codebase?
520
+ - What patterns suggest "happy path only" thinking?
521
+ - Where is defensive programming absent?
522
+
523
+ 2. **Attack Surface Summary**:
524
+ - List all entry points (APIs, webhooks, file uploads, etc.)
525
+ - Which have weakest protection?
526
+ - What can an attacker do without authentication?
527
+
528
+ 3. **Business Logic Abuse**:
529
+ - Can users get free money/credits/access?
530
+ - Can users manipulate pricing/quantities?
531
+ - Can users access other users' data?
532
+ - Can users escalate privileges?
533
+
534
+ 4. **Economic Attacks** (AI never thinks about these):
535
+ - Resource exhaustion (create unlimited X)
536
+ - Referral abuse
537
+ - Trial abuse
538
+ - Rate limit bypass for profit
539
+
540
+ 5. **Chain Attacks**:
541
+ - Which LOW findings combine into HIGH/CRITICAL?
542
+ - What's the worst-case attack scenario?
543
+
544
+ 6. **Missing Controls Checklist**:
545
+ [ ] Input validation on all endpoints
546
+ [ ] Output encoding for all user data
547
+ [ ] Authentication on all non-public routes
548
+ [ ] Authorization checks for all resources
549
+ [ ] Rate limiting on all endpoints
550
+ [ ] Audit logging for security events
551
+ [ ] Error handling that doesn't leak info
552
+ [ ] CSRF protection on state-changing operations
553
+
554
+ Write to .coverme/agents/ADVERSARIAL.json:
872
555
  {
873
- "id": "AUTH-001",
874
- "title": "JWT Accepts 'none' Algorithm - Authentication Bypass",
875
- "severity": "critical",
876
- "category": "security",
877
- "file": "src/middleware/auth.ts",
878
- "line": 34,
879
- "endLine": 34,
880
- "code": "jwt.verify(token, secret, { algorithms: ['HS256', 'none'] })",
881
-
882
- "description": "JWT verification explicitly allows the 'none' algorithm. An attacker can forge tokens by removing the signature and setting alg='none'. This is a COMPLETE authentication bypass.",
883
-
884
- "impact": "Total authentication bypass. Attacker can:\n1. Impersonate any user (including admins)\n2. Access all protected endpoints\n3. Modify/delete any data\n4. Create backdoor admin accounts",
885
-
886
- "businessImpact": {
887
- "financial": "Complete data breach. GDPR fine: €20M or 4% revenue. Average breach cost: $4.35M",
888
- "reputation": "Loss of customer trust. 81% users abandon service after auth breach (Okta 2023)",
889
- "legal": "Class action lawsuit risk. Negligence claim - 'none' algorithm is well-known vulnerability",
890
- "operational": "Full incident response, forensics, password reset for all users, potential service shutdown"
891
- },
892
-
893
- "realWorldExamples": [
894
- "Auth0 CVE-2015-9235: 'none' algorithm allowed → millions of tokens compromised",
895
- "Pfsense (2018): JWT 'none' bypass → full admin access to firewall configs",
896
- "Your scenario: Attacker becomes admin, exports entire customer database, posts on dark web"
897
- ],
898
-
899
- "attackChain": [
900
- {"step": 1, "action": "Register normal user account, capture JWT from /api/login", "result": "Valid token: eyJhbGc..."},
901
- {"step": 2, "action": "Base64 decode header, change {\"alg\":\"HS256\"} to {\"alg\":\"none\"}", "result": "Forged header"},
902
- {"step": 3, "action": "Change payload to {\"userId\":1,\"role\":\"admin\"}, remove signature", "result": "Admin token without signature"},
903
- {"step": 4, "action": "Send to /api/admin/users with forged token", "result": "Returns all users - authentication bypassed"}
904
- ],
905
-
906
- "proofOfConcept": "# Exploit the vulnerability:\n\n# 1. Get valid token\nTOKEN=$(curl -X POST https://api.example.com/login \\\n -d '{\"email\":\"attacker@evil.com\",\"password\":\"pass123\"}' | jq -r .token)\n\n# 2. Forge admin token (Python)\npython3 << EOF\nimport base64\nimport json\n\n# Decode original token parts\nheader = {\"alg\": \"none\", \"typ\": \"JWT\"}\npayload = {\"userId\": 1, \"role\": \"admin\", \"exp\": 9999999999}\n\n# Encode without signature\nforged = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b'=') + b'.'\nforged += base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b'=') + b'.'\n\nprint(forged.decode())\nEOF\n\n# 3. Use forged token\ncurl https://api.example.com/admin/users \\\n -H \"Authorization: Bearer eyJhbGc...\" \\\n # Result: Full user database returned",
907
-
908
- "recommendation": "Remove 'none' from algorithms array:\n\n```typescript\n// ✅ SECURE - Only allow HS256\njwt.verify(token, secret, { algorithms: ['HS256'] })\n```",
909
-
910
- "quickFix": {
911
- "description": "Remove 'none' from algorithms array (5 minutes)",
912
- "code": "jwt.verify(token, secret, { algorithms: ['HS256'] })",
913
- "limitations": "Still using symmetric key (HS256) - shared between services. Consider asymmetric (RS256) for multi-service architecture."
914
- },
915
-
916
- "properFix": {
917
- "description": "Upgrade to RS256 with public/private key pairs (4 hours)",
918
- "code": "// Generate key pair (run once)\n// openssl genrsa -out private.key 2048\n// openssl rsa -in private.key -pubout -out public.key\n\nimport fs from 'fs';\nimport jwt from 'jsonwebtoken';\n\nconst publicKey = fs.readFileSync('public.key');\n\n// Verify with public key only\nfunction verifyToken(token: string) {\n try {\n const decoded = jwt.verify(token, publicKey, {\n algorithms: ['RS256'], // Only asymmetric\n issuer: 'your-service',\n audience: 'your-api'\n });\n return decoded;\n } catch (err) {\n throw new AuthError('Invalid token', { cause: err });\n }\n}",
919
- "additionalSteps": [
920
- "Store private key in secure vault (AWS Secrets Manager, HashiCorp Vault)",
921
- "Add key rotation policy (rotate every 90 days)",
922
- "Implement token revocation list (Redis with TTL)",
923
- "Add JWT ID (jti) claim for replay protection",
924
- "Monitor for suspicious token patterns (e.g., expired tokens, wrong issuer)"
925
- ]
926
- },
927
-
928
- "testing": {
929
- "description": "Verify the fix prevents 'none' algorithm attacks",
930
- "manual": [
931
- "Test 1: Forge token with alg='none' → should reject with 'invalid algorithm'",
932
- "Test 2: Valid HS256 token → should work",
933
- "Test 3: Token with wrong signature → should reject",
934
- "Test 4: Expired token → should reject"
935
- ],
936
- "automated": "describe('JWT security', () => {\n it('should reject none algorithm', () => {\n const forgedToken = 'eyJhbGciOiJub25lIn0.eyJ1c2VySWQiOjF9.';\n \n expect(() => {\n verifyToken(forgedToken);\n }).toThrow('invalid algorithm');\n });\n \n it('should only accept HS256', () => {\n const validToken = jwt.sign({ userId: 1 }, secret, { algorithm: 'HS256' });\n const decoded = verifyToken(validToken);\n expect(decoded.userId).toBe(1);\n \n // RS256 should fail\n const rs256Token = jwt.sign({ userId: 1 }, privateKey, { algorithm: 'RS256' });\n expect(() => verifyToken(rs256Token)).toThrow();\n });\n});"
937
- },
938
-
939
- "detection": {
940
- "description": "Check if this vulnerability was already exploited",
941
- "commands": [
942
- "# Check logs for tokens with 'none' algorithm",
943
- "grep 'eyJhbGciOiJub25lIi' /var/log/nginx/access.log",
944
- "",
945
- "# Decode suspicious tokens from logs",
946
- "cat access.log | grep 'Authorization: Bearer' | cut -d' ' -f3 | while read token; do",
947
- " echo $token | cut -d. -f1 | base64 -d",
948
- "done | grep '\"alg\":\"none\"'",
949
- "",
950
- "# Check for admin actions from non-admin users",
951
- "SELECT * FROM audit_log WHERE action LIKE 'admin.%' AND user_id NOT IN (SELECT id FROM users WHERE role='admin');"
952
- ],
953
- "indicators": [
954
- "Tokens in logs with alg='none' in header",
955
- "Admin actions performed by non-admin user IDs",
956
- "Unusual API access patterns (e.g., all endpoints accessed by one user)",
957
- "Failed JWT verification errors followed by successful requests"
958
- ]
959
- },
960
-
961
- "dread": {
962
- "damage": 10,
963
- "reproducibility": 10,
964
- "exploitability": 9,
965
- "affectedUsers": 10,
966
- "discoverability": 7,
967
- "score": 9.2
968
- },
969
-
970
- "cwe": "CWE-347",
971
- "owasp": "A02:2021-Cryptographic Failures",
972
- "cvss": "9.8 (Critical)",
973
-
974
- "references": [
975
- "https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/",
976
- "https://cwe.mitre.org/data/definitions/347.html",
977
- "https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/10-Testing_JSON_Web_Tokens"
978
- ],
979
-
980
- "evidence": [
981
- "algorithms array at line 34 includes 'none'",
982
- "No additional signature validation",
983
- "Endpoint /api/admin uses this middleware (routes.ts:89)",
984
- "No issuer/audience validation - accepts any token structure",
985
- "Secret key hardcoded in config file (not rotated)"
986
- ],
987
-
988
- "fixOwner": "developer",
989
- "estimatedEffort": {
990
- "human": "4-6 hours (research JWT best practices, implement RS256, generate key pairs, update auth flow, test)",
991
- "claudeCode": "20-30 minutes (updates jwt.verify config, generates RS256 implementation, creates key management code, writes tests)",
992
- "roi": "12x faster with Claude Code"
993
- },
994
- "priority": 1
556
+ "systemicWeaknesses": ["..."],
557
+ "missingControls": ["..."],
558
+ "attackSurface": {"unauthenticated": [...], "authenticated": [...]},
559
+ "worstCaseScenario": "...",
560
+ "chainAttacks": [{"chain": [...], "impact": "..."}],
561
+ "prioritizedRisks": ["..."]
995
562
  }
563
+
564
+ Return ONLY: "done"
996
565
  ```
997
566
 
998
- ### Excellent Performance Finding (Do This!)
567
+ ---
999
568
 
1000
- ```json
1001
- {
1002
- "id": "PERF-001",
1003
- "title": "N+1 Query in User Dashboard - 3000ms Page Load",
1004
- "severity": "high",
1005
- "category": "performance",
1006
- "file": "src/controllers/dashboardController.ts",
1007
- "line": 45,
1008
- "endLine": 52,
1009
- "code": "const users = await User.findAll();\nfor (const user of users) {\n user.orders = await Order.findByUserId(user.id);\n}",
1010
-
1011
- "description": "Dashboard loads all users (1,000+) then makes individual database query for each user's orders. 1 query to get users + 1,000 queries for orders = 1,001 total queries. At 3ms per query = 3+ seconds page load.",
1012
-
1013
- "impact": "Severe performance degradation. Page load time increases linearly with user count:\n- 100 users: 300ms\n- 1,000 users: 3,000ms (current)\n- 10,000 users: 30,000ms (unusable)\n\nDatabase CPU spikes to 90% during peak hours. Users abandon page before it loads.",
1014
-
1015
- "businessImpact": {
1016
- "financial": "53% users abandon pages loading >3s (Google). At 10k visits/day × $50 conversion = $265k/year lost revenue",
1017
- "reputation": "Poor reviews mentioning 'slow dashboard'. PageSpeed score: 23/100",
1018
- "operational": "Database overload causes cascading failures. RDS CPU alerts firing 20x/day",
1019
- "scalability": "Cannot scale past 1,000 users without major infrastructure upgrade"
1020
- },
1021
-
1022
- "realWorldExamples": [
1023
- "Shopify (2015): N+1 queries → 20s checkout → fixed with eager loading → 2s",
1024
- "Your scenario: Admin dashboard times out during business hours",
1025
- "Industry data: N+1 queries are #2 cause of slow Rails apps (Rails community survey)"
1026
- ],
1027
-
1028
- "attackChain": [
1029
- {"step": 1, "action": "Normal user visits /dashboard", "result": "Triggers 1,001 database queries"},
1030
- {"step": 2, "action": "Attacker sends 10 concurrent requests", "result": "10,010 queries → database CPU 95%"},
1031
- {"step": 3, "action": "Legitimate users affected", "result": "All API requests slow down"},
1032
- {"step": 4, "action": "Attacker continues requests", "result": "Accidental DoS - database becomes unresponsive"}
1033
- ],
1034
-
1035
- "proofOfConcept": "# Measure the N+1 problem:\n\n# 1. Enable query logging\nDATABASE_LOG_QUERIES=true npm start\n\n# 2. Load dashboard\ncurl https://api.example.com/dashboard\n\n# 3. Count queries in log\ngrep 'SELECT.*FROM orders' logs/db.log | wc -l\n# Result: 1000+ queries\n\n# 4. Measure timing\ntime curl https://api.example.com/dashboard\n# Result: real 3.2s",
1036
-
1037
- "recommendation": "Use eager loading (JOIN) to fetch all data in one query:\n\n```typescript\n// ✅ OPTIMIZED - Single query with JOIN\nconst users = await User.findAll({\n include: [{\n model: Order,\n as: 'orders'\n }]\n});\n\n// SQL generated:\n// SELECT users.*, orders.*\n// FROM users\n// LEFT JOIN orders ON orders.user_id = users.id\n// (1 query instead of 1,001)\n```",
1038
-
1039
- "quickFix": {
1040
- "description": "Add eager loading to existing query (30 minutes)",
1041
- "code": "const users = await User.findAll({\n include: ['orders'] // Sequelize eager loading\n});",
1042
- "limitations": "Still loads all users - may be slow with 10k+ users. Pagination recommended."
1043
- },
1044
-
1045
- "properFix": {
1046
- "description": "Eager loading + pagination + caching (4 hours)",
1047
- "code": "// Proper solution with pagination\nasync function getDashboard(page = 1, limit = 50) {\n const cacheKey = `dashboard:${page}`;\n \n // Check cache first\n const cached = await redis.get(cacheKey);\n if (cached) return JSON.parse(cached);\n \n // Single query with JOIN + pagination\n const users = await User.findAll({\n include: [{\n model: Order,\n as: 'orders',\n limit: 10 // Limit orders per user\n }],\n limit,\n offset: (page - 1) * limit,\n order: [['createdAt', 'DESC']]\n });\n \n // Cache for 5 minutes\n await redis.setex(cacheKey, 300, JSON.stringify(users));\n \n return users;\n}",
1048
- "additionalSteps": [
1049
- "Add database index on orders.user_id (if missing)",
1050
- "Consider materialized view for dashboard data",
1051
- "Add connection pooling (min: 5, max: 20)",
1052
- "Set up read replicas for heavy queries",
1053
- "Monitor query performance with APM (DataDog, New Relic)"
1054
- ]
1055
- },
1056
-
1057
- "testing": {
1058
- "description": "Verify performance improvement",
1059
- "manual": [
1060
- "Test 1: Load dashboard, check DB logs → should see 1-2 queries (not 1000+)",
1061
- "Test 2: Use Chrome DevTools → Time to First Byte should be <500ms",
1062
- "Test 3: Run with 10k users in test DB → should still load <1s",
1063
- "Test 4: Check database CPU during load → should stay <50%"
1064
- ],
1065
- "automated": "describe('Dashboard performance', () => {\n it('should use eager loading (no N+1)', async () => {\n // Track queries\n const queries = [];\n db.on('query', q => queries.push(q));\n \n await getDashboard();\n \n // Should be 1 SELECT with JOIN\n expect(queries.length).toBeLessThan(5);\n expect(queries[0]).toContain('JOIN orders');\n });\n \n it('should load dashboard in <500ms', async () => {\n const start = Date.now();\n await getDashboard();\n const duration = Date.now() - start;\n \n expect(duration).toBeLessThan(500);\n });\n});"
1066
- },
1067
-
1068
- "detection": {
1069
- "description": "Find other N+1 query problems in codebase",
1070
- "commands": [
1071
- "# Find loops with database queries inside",
1072
- "grep -r 'for.*await.*find' src/",
1073
- "grep -r '.map.*await' src/",
1074
- "",
1075
- "# Check database slow query log",
1076
- "cat /var/log/postgresql/slow-queries.log | grep 'SELECT.*FROM orders'",
1077
- "",
1078
- "# Use database profiler",
1079
- "npm install --save-dev sequelize-profiler",
1080
- "# Add to app: db.use(require('sequelize-profiler'))"
1081
- ],
1082
- "indicators": [
1083
- "Database query count proportional to result set size",
1084
- "Slow query log shows same query repeated 100+ times",
1085
- "APM shows 'database' taking 80%+ of response time",
1086
- "Database CPU spikes during list page loads"
1087
- ]
1088
- },
1089
-
1090
- "dread": {
1091
- "damage": 7,
1092
- "reproducibility": 10,
1093
- "exploitability": 10,
1094
- "affectedUsers": 10,
1095
- "discoverability": 8,
1096
- "score": 9.0
1097
- },
1098
-
1099
- "references": [
1100
- "https://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations",
1101
- "https://sequelize.org/docs/v6/advanced-association-concepts/eager-loading/",
1102
- "https://use-the-index-luke.com/"
1103
- ],
1104
-
1105
- "evidence": [
1106
- "Loop at line 46 calls Order.findByUserId() inside",
1107
- "No 'include' option in User.findAll() query",
1108
- "APM data shows 1,247 queries for single dashboard load",
1109
- "Database slow query log: 'SELECT * FROM orders WHERE user_id = ?' appears 1000+ times",
1110
- "PageSpeed Insights: Time to Interactive = 3.2s"
1111
- ],
1112
-
1113
- "fixOwner": "developer",
1114
- "estimatedEffort": {
1115
- "human": "3-4 hours (find all N+1 queries, research eager loading, implement pagination, add caching, performance test)",
1116
- "claudeCode": "15-20 minutes (detects N+1 patterns, converts to eager loading, adds pagination and caching, generates performance tests)",
1117
- "roi": "12x faster with Claude Code"
1118
- },
1119
- "priority": 1
1120
- }
1121
- ```
569
+ ## Phase 3: Aggregate Results
1122
570
 
1123
- ### Excellent Architecture Finding (Do This!)
571
+ **CRITICAL: Use Write tool directly, NOT bash heredoc**
1124
572
 
1125
- ```json
1126
- {
1127
- "id": "ARCH-001",
1128
- "title": "Payment Secrets Hardcoded in Repository - Exposure Risk",
1129
- "severity": "critical",
1130
- "category": "architecture",
1131
- "file": "src/config/payment.ts",
1132
- "line": 12,
1133
- "endLine": 12,
1134
- "code": "const STRIPE_SECRET_KEY = 'sk_live_51Hqr2x...'",
1135
-
1136
- "description": "Stripe LIVE secret key hardcoded in source code. Key has been committed to git history (commit abc123). Anyone with repository access can process payments, issue refunds, export customer data.",
1137
-
1138
- "impact": "Complete payment system compromise:\n1. Process fraudulent charges\n2. Issue refunds to attacker's accounts\n3. Export all customer payment data (PCI violation)\n4. Delete customer payment methods\n5. Key exposed in git history - even if removed now, still accessible",
1139
-
1140
- "businessImpact": {
1141
- "financial": "Fraudulent charges/refunds = unlimited financial loss. Stripe may suspend account. PCI Level 1 fine: $5k-$100k/month",
1142
- "reputation": "PCI compliance failure = cannot process credit cards. Customer data breach = loss of trust",
1143
- "legal": "PCI DSS violation = potential lawsuits. FTC investigation. Payment processor termination",
1144
- "operational": "Emergency key rotation, customer notification, forensic investigation, potential service shutdown"
1145
- },
1146
-
1147
- "realWorldExamples": [
1148
- "Uber (2016): AWS keys in GitHub → 57M users exposed → $148M settlement",
1149
- "Twitter (2020): API keys leaked → account takeovers including Obama, Biden",
1150
- "Your risk: Developer laptop stolen → attacker has payment keys → can issue refunds to themselves"
1151
- ],
1152
-
1153
- "attackChain": [
1154
- {"step": 1, "action": "Clone repository or access via ex-employee's account", "result": "Source code with secret key"},
1155
- {"step": 2, "action": "Use key to list all customers: curl https://api.stripe.com/v1/customers -u sk_live_...", "result": "Export entire customer database"},
1156
- {"step": 3, "action": "Issue refunds to attacker-controlled accounts", "result": "$10k+ fraudulent refunds"},
1157
- {"step": 4, "action": "Even if key rotated, check git history: git log -p config/payment.ts", "result": "Original key still in commits"}
1158
- ],
1159
-
1160
- "proofOfConcept": "# Exploit hardcoded secret:\n\n# 1. Find the key in code\ngrep -r 'sk_live' .\n# Result: src/config/payment.ts:12:const STRIPE_SECRET_KEY = 'sk_live_51Hqr2x...'\n\n# 2. Check git history (even if removed)\ngit log --all -p | grep 'sk_live'\n# Result: Found in commits abc123, def456, ghi789\n\n# 3. Use the key to issue refund\ncurl https://api.stripe.com/v1/refunds \\\n -u sk_live_51Hqr2x...: \\\n -d charge=ch_xyz123 \\\n -d amount=10000\n# Result: $100 refunded to attacker's card",
1161
-
1162
- "recommendation": "Move secrets to environment variables and secret manager:\n\n```typescript\n// ✅ SECURE - Load from environment\nconst STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;\n\nif (!STRIPE_SECRET_KEY) {\n throw new Error('STRIPE_SECRET_KEY environment variable required');\n}\n```",
1163
-
1164
- "quickFix": {
1165
- "description": "Move to .env file (NOT committed) - 1 hour",
1166
- "code": "// .env (add to .gitignore)\nSTRIPE_SECRET_KEY=sk_live_51Hqr2x...\n\n// src/config/payment.ts\nimport dotenv from 'dotenv';\ndotenv.config();\n\nconst STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;",
1167
- "limitations": ".env still on server filesystem. If server compromised, key exposed. Better: use secret manager."
1168
- },
1169
-
1170
- "properFix": {
1171
- "description": "Migrate to AWS Secrets Manager with key rotation (1 day)",
1172
- "code": "import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';\n\nconst client = new SecretsManagerClient({ region: 'us-east-1' });\n\n// Fetch secret from AWS Secrets Manager\nasync function getStripeKey(): Promise<string> {\n const response = await client.send(\n new GetSecretValueCommand({ SecretId: 'prod/stripe/secret_key' })\n );\n \n if (!response.SecretString) {\n throw new Error('Stripe secret not found in Secrets Manager');\n }\n \n return JSON.parse(response.SecretString).STRIPE_SECRET_KEY;\n}\n\n// Cache for 5 minutes (secrets manager charges per request)\nlet cachedKey: string | null = null;\nlet cacheExpiry = 0;\n\nexport async function getPaymentKey(): Promise<string> {\n if (cachedKey && Date.now() < cacheExpiry) {\n return cachedKey;\n }\n \n cachedKey = await getStripeKey();\n cacheExpiry = Date.now() + 5 * 60 * 1000;\n return cachedKey;\n}",
1173
- "additionalSteps": [
1174
- "Rotate Stripe secret key IMMEDIATELY (current key is compromised)",
1175
- "Enable automatic key rotation in AWS Secrets Manager (90 days)",
1176
- "Remove key from ALL git history: git filter-branch or BFG Repo-Cleaner",
1177
- "Audit Stripe logs for suspicious activity (past 90 days)",
1178
- "Set up IAM roles - only production servers can read secrets",
1179
- "Enable CloudTrail logging for secret access",
1180
- "Add alerts for secret access from unexpected IPs",
1181
- "Document key rotation runbook"
1182
- ]
1183
- },
1184
-
1185
- "testing": {
1186
- "description": "Verify secrets are properly secured",
1187
- "manual": [
1188
- "Test 1: grep -r 'sk_live' . → should return 0 results",
1189
- "Test 2: git log --all -p | grep 'sk_live' → check if still in history",
1190
- "Test 3: docker run --rm app → should fail with 'STRIPE_SECRET_KEY required'",
1191
- "Test 4: AWS Secrets Manager console → verify secret exists",
1192
- "Test 5: Attempt to access secret from dev laptop → should fail (IAM)"
1193
- ],
1194
- "automated": "describe('Secret management', () => {\n it('should not have hardcoded secrets', () => {\n const files = glob.sync('**/*.{ts,js}');\n files.forEach(file => {\n const content = fs.readFileSync(file, 'utf8');\n expect(content).not.toMatch(/sk_live_[a-zA-Z0-9]{32}/);\n expect(content).not.toMatch(/pk_live_[a-zA-Z0-9]{32}/);\n });\n });\n \n it('should require environment variables', () => {\n delete process.env.STRIPE_SECRET_KEY;\n expect(() => require('./config/payment')).toThrow('STRIPE_SECRET_KEY');\n });\n});"
1195
- },
1196
-
1197
- "detection": {
1198
- "description": "Find ALL hardcoded secrets in codebase",
1199
- "commands": [
1200
- "# Find Stripe keys",
1201
- "git log --all -p | grep -E 'sk_live_[a-zA-Z0-9]+'",
1202
- "",
1203
- "# Find AWS keys",
1204
- "git log --all -p | grep -E 'AKIA[A-Z0-9]{16}'",
1205
- "",
1206
- "# Find generic secrets (high entropy strings)",
1207
- "trufflehog git file://. --only-verified",
1208
- "",
1209
- "# Use automated scanner",
1210
- "npm install -g detect-secrets",
1211
- "detect-secrets scan --all-files",
1212
- "",
1213
- "# Check Stripe for unauthorized activity",
1214
- "# Login to Stripe dashboard → Developers → Logs → Filter by IP address"
1215
- ],
1216
- "indicators": [
1217
- "Stripe keys (sk_live_, pk_live_) in source code",
1218
- "AWS credentials (AKIA...) in config files",
1219
- "High entropy strings (40+ random chars) in code",
1220
- "Suspicious Stripe activity: refunds from unknown IPs, customer exports",
1221
- "GitHub secret scanning alerts (if repo is on GitHub)"
1222
- ]
1223
- },
1224
-
1225
- "dread": {
1226
- "damage": 10,
1227
- "reproducibility": 10,
1228
- "exploitability": 10,
1229
- "affectedUsers": 10,
1230
- "discoverability": 9,
1231
- "score": 9.8
1232
- },
1233
-
1234
- "cwe": "CWE-798",
1235
- "owasp": "A02:2021-Cryptographic Failures",
1236
- "cvss": "10.0 (Critical)",
1237
-
1238
- "references": [
1239
- "https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html",
1240
- "https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password",
1241
- "https://stripe.com/docs/keys#safe-keys"
1242
- ],
1243
-
1244
- "evidence": [
1245
- "Line 12: const STRIPE_SECRET_KEY = 'sk_live_51Hqr2x...'",
1246
- "Git history shows key in 14 commits dating back 6 months",
1247
- "Repository has 23 contributors (all have access to key)",
1248
- "No .gitignore entry for config files",
1249
- "GitHub shows 'Secret scanning alert' for this repository"
1250
- ],
1251
-
1252
- "fixOwner": "devops + developer",
1253
- "estimatedEffort": {
1254
- "human": "1-2 days (setup AWS Secrets Manager, migrate all secrets, update deployment scripts, rotate keys, audit git history, cleanup with BFG)",
1255
- "claudeCode": "1-2 hours (finds all secrets, generates Secrets Manager integration, updates code, creates rotation scripts, provides git cleanup commands)",
1256
- "roi": "12x faster with Claude Code"
1257
- },
1258
- "priority": 1
1259
- }
573
+ 1. List agent files:
574
+ ```bash
575
+ ls .coverme/agents/*.json 2>/dev/null | head -30
1260
576
  ```
1261
577
 
1262
- ### Bad Finding (Don't Do This!)
578
+ 2. Read each agent JSON file using the Read tool (in parallel if possible)
1263
579
 
580
+ 3. **Use the Write tool** to save `.coverme/scan.json` with this structure:
1264
581
  ```json
1265
582
  {
1266
- "id": "SEC-001",
1267
- "title": "SQL Injection",
1268
- "severity": "high",
1269
- "description": "There might be SQL injection somewhere"
583
+ "projectName": "from package.json or folder name",
584
+ "scanDate": "ISO timestamp",
585
+ "filesScanned": N,
586
+ "linesOfCode": N,
587
+ "findings": [merged from all agent files, deduplicated],
588
+ "positiveObservations": [from POSITIVE.json],
589
+ "summary": {"critical":N,"high":N,"medium":N,"low":N}
1270
590
  }
1271
591
  ```
1272
592
 
1273
- ---
1274
-
1275
- ## REMEMBER
1276
-
1277
- 1. **CREATE DETAILED FINDINGS** - DO NOT just write executiveSummary! You MUST populate the `findings` array with full finding objects!
1278
- 2. **Silent failures are CRITICAL** - They hide production bugs in payments, auth, data
1279
- 3. **Read actual code** - Don't guess, read the files
1280
- 4. **Check git history** - Secrets may have been removed but still exposed
1281
- 5. **Think like an attacker** - How would you exploit this?
1282
- 6. **Be specific** - File:line, code snippets, attack chains
1283
- 7. **DREAD + Attack Chain** - Required for critical/high
1284
- 8. **Quality over quantity** - 10 solid findings > 50 vague ones
1285
- 9. **Architecture matters** - Trust boundaries, data flow, scalability
1286
- 10. **Performance impacts security** - N+1 queries → DoS, memory leaks → crashes
1287
- 11. **Include ROI estimates** - human vs claudeCode time for every finding
1288
- 12. **Run `coverme report`** - Not done until HTML opens!
593
+ **IMPORTANT**:
594
+ - Use Write tool, not bash echo/cat
595
+ - Keep max 50 findings (prioritize by severity)
596
+ - Max 3 code snippets per finding
1289
597
 
1290
598
  ---
1291
599
 
1292
- ⚠️ **FINAL CHECK BEFORE SUBMITTING scan.json:**
600
+ ## Phase 4: Generate Report
1293
601
 
1294
- - [ ] `findings` array contains at least 3-10 detailed finding objects (NOT empty!)
1295
- - [ ] Each finding has businessImpact, proofOfConcept, attackChain, quickFix, properFix, testing, detection, estimatedEffort
1296
- - [ ] executiveSummary.topRisks matches the findings in the findings array
1297
- - [ ] summary counts (critical/high/medium/low) match the findings array length
602
+ ```bash
603
+ TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
604
+ npx coverme-scanner report .coverme/scan.json -f html -o ".coverme/report_$TIMESTAMP.html"
605
+ open ".coverme/report_$TIMESTAMP.html"
606
+ ```
1298
607
 
1299
608
  ---
1300
609
 
1301
- START SCANNING NOW. Be methodical, thorough, and think deeply. Your reputation depends on finding what others miss.
610
+ ## DONE
611
+
612
+ Tell user: "Scan complete! Report opened."