coverme-scanner 1.10.1 → 1.11.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.
@@ -1,2422 +1,298 @@
1
- # CoverMe Multi-Agent Scan Orchestration
1
+ # CoverMe Security Scanner
2
2
 
3
- **Ultrathink** - Analyze deeply, consider edge cases, trace data flows completely.
3
+ You are a senior security consultant performing a comprehensive security assessment.
4
4
 
5
- Execute this multi-agent security scan with cross-validation.
5
+ **Ultrathink** - Analyze deeply, read actual code, trace data flows.
6
6
 
7
7
  ---
8
8
 
9
- ## CRITICAL: FILE-BASED AGENT OUTPUT (Prevents Token Overflow)
9
+ ## PHASE 1: DISCOVERY
10
10
 
11
- **Each agent MUST save its findings to a file instead of returning them to the orchestrator.**
12
-
13
- This prevents the orchestrator from hitting max tokens when consolidating 17+ agents.
14
-
15
- ### Agent Output Rules:
16
-
17
- 1. **Each agent saves to**: `.coverme/agents/{AGENT_ID}.json`
18
- 2. **Create directory first**: `mkdir -p .coverme/agents`
19
- 3. **Agent returns ONLY**: `{"status": "complete", "file": ".coverme/agents/SEC.json", "findingsCount": 5}`
20
- 4. **Orchestrator reads files** after all agents complete
21
-
22
- ### Agent Output File Format:
23
- ```json
24
- {
25
- "agentId": "SEC",
26
- "agentName": "Security Core Scanner",
27
- "scanDate": "2026-02-18T10:00:00Z",
28
- "duration": "45s",
29
- "findings": [...],
30
- "positives": [...],
31
- "skipped": false,
32
- "skipReason": null
33
- }
34
- ```
35
-
36
- ### Orchestrator Consolidation:
37
- ```bash
38
- # After all agents complete, read all findings:
39
- cat .coverme/agents/*.json | jq -s 'map(.findings) | flatten'
40
- ```
41
-
42
- This architecture allows unlimited agents without token overflow.
43
-
44
- ---
45
-
46
- ## PHASE 0: PROJECT DISCOVERY & ARCHITECTURE MAPPING
47
-
48
- Before scanning, understand what you're scanning and build the architecture map.
49
-
50
- ### Step 0: Initialize Agent Output Directory
51
-
52
- ```bash
53
- mkdir -p .coverme/agents
54
- ```
55
-
56
- ### Step 1: Gather Project Statistics
57
-
58
- ### Step 1: Gather Project Statistics
59
-
60
- ```bash
61
- # List ALL top-level directories (excluding hidden, node_modules, dist, build)
62
- ls -d */ 2>/dev/null | grep -v -E '^(node_modules|dist|build|\.)/
63
-
64
- # Count files and lines of code
65
- find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.tsx" -o -name "*.jsx" -o -name "*.py" -o -name "*.go" -o -name "*.java" -o -name "*.rb" -o -name "*.php" -o -name "*.cs" -o -name "*.swift" -o -name "*.kt" \) -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" -not -path "*/build/*" -not -path "*/__pycache__/*" | wc -l
66
-
67
- # Count lines of code (approximate)
68
- find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.tsx" -o -name "*.jsx" -o -name "*.py" -o -name "*.go" \) -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" 2>/dev/null | head -100 | xargs wc -l 2>/dev/null | tail -1
69
-
70
- # Generate project tree (2 levels deep)
71
- find . -maxdepth 2 -type d -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" -not -path "*/__pycache__/*" -not -path "*/build/*" | sort
72
- ```
73
-
74
- ### Step 2: Read Project Info
75
-
76
- ```bash
77
- cat package.json 2>/dev/null | head -30
78
- cat README.md 2>/dev/null | head -100
79
- ls -la
80
- ls src/ 2>/dev/null || ls app/ 2>/dev/null || ls lib/ 2>/dev/null
81
- ```
82
-
83
- ### Step 3: Create Project Overview
84
-
85
- Include these statistics in the final report:
86
-
87
- ```json
88
- {
89
- "filesScanned": 45,
90
- "linesOfCode": 4850,
91
- "projectTree": "project-name/\n├── src/\n│ ├── api/\n│ ├── services/\n│ └── utils/\n├── tests/\n└── package.json",
92
- "projectOverview": {
93
- "name": "project-name",
94
- "type": "Backend API | Frontend SPA | Full-stack | CLI | Library | Microservice",
95
- "stack": ["Node.js", "TypeScript", "React", "PostgreSQL", "Redis"],
96
- "purpose": "1-2 sentence description of what this project does",
97
- "architecture": "Monolith | Microservices | Serverless | Hybrid",
98
- "keyComponents": ["backend-api/", "frontend/", "services/", "packages/", "etc"]
99
- }
100
- }
101
- ```
102
-
103
- **IMPORTANT**:
104
- - `filesScanned` - Count of source code files analyzed (not node_modules/dist)
105
- - `linesOfCode` - Total lines in source files (approximate is fine)
106
- - `projectTree` - ASCII tree representation of main directories (use tree format with ├── and └──)
107
- - `keyComponents` - **MUST include ALL top-level directories** containing source code. Do NOT skip any directory. List every folder from `ls -d */` excluding node_modules/dist/build/.git
108
-
109
- This context helps readers understand the security findings in context.
110
-
111
- ### Step 3: Check for Previous Scan Results
112
-
113
- ```bash
114
- cat .coverme/scan.json 2>/dev/null | head -5 || echo "NO_PREVIOUS_SCAN"
115
- ```
116
-
117
- **IF previous scan.json exists:**
118
- - Load previous findings to track what was resolved since the last scan
119
- - Compare current findings against previous findings
120
- - Any finding from previous scan NOT found in current scan = "Previously Resolved"
121
- - Include a `previouslyResolved` array in the final output showing what was fixed
122
- - This builds trust and shows security progress over time
123
-
124
- **Format for previously resolved:**
125
- ```json
126
- {
127
- "id": "PREV-001",
128
- "title": "Original finding title from previous scan",
129
- "originalSeverity": "critical|high|medium|low",
130
- "resolution": "How it was fixed — be specific: 'Replaced string concatenation with parameterized queries via Prisma ORM. Verified no raw SQL remains.'",
131
- "resolvedDate": "Date of current scan"
132
- }
133
- ```
134
-
135
- **Example Previously Resolved section (from Officely report):**
136
- - "DuckDB SQL Injection (was CRITICAL) — Resolved: enable_external_access=false sandbox + comprehensive SQL validation blocklist."
137
- - "Admin API Fail-Open (was HIGH) — Resolved: Binds to 127.0.0.1, fail-closed when no ADMIN_ALLOWED_IPS. Three-layer defense."
138
- - "Redis KEYS in Production (was HIGH) — Resolved: All paths now use SCAN via cursor-based scanKeys()."
139
-
140
- **IF NO previous scan:**
141
- - Skip — set `previouslyResolved` to empty array `[]`
142
-
143
- ### Step 4: Check for Runtime Verification (SSH)
144
-
145
- ```bash
146
- cat .coverme/runtime.json 2>/dev/null || echo "NO_RUNTIME_CONFIG"
147
- ```
148
-
149
- **IF runtime.json exists with environments:**
150
- - Runtime verification is ENABLED
151
- - Store the SSH details for use in AGENT 22 (Runtime Verification)
152
- - The agent will SSH to compare actual runtime vs code expectations
153
-
154
- **IF NO runtime.json:**
155
- - Runtime verification is DISABLED (skip AGENT 22)
156
- - This is normal - many projects don't need runtime verification
157
-
158
- ### Step 5: Architecture Discovery (AGENT 0)
159
-
160
- **This runs FIRST, before all other agents. Its output feeds into every subsequent agent.**
161
-
162
- Build a comprehensive architecture map by analyzing:
163
-
164
- ```bash
165
- # Detect databases
166
- grep -r -l "prisma\|mongoose\|sequelize\|typeorm\|pg\|mysql\|redis\|mongodb" --include="*.json" --include="*.ts" --include="*.js" . 2>/dev/null | head -5
167
-
168
- # Detect auth providers
169
- grep -r -l "clerk\|auth0\|firebase.auth\|passport\|next-auth\|supabase.auth" --include="*.ts" --include="*.js" . 2>/dev/null | head -5
170
-
171
- # Detect external APIs
172
- grep -r "fetch\|axios\|got\|request" --include="*.ts" --include="*.js" . 2>/dev/null | grep -v node_modules | head -10
173
-
174
- # Detect infrastructure
175
- ls -la Dockerfile docker-compose* k8s/ helm/ .github/workflows/ 2>/dev/null
176
- ```
177
-
178
- **Save architecture map to `.coverme/agents/ARCH-D.json`:**
179
- ```json
180
- {
181
- "agentId": "ARCH-D",
182
- "agentName": "Architecture Discovery",
183
- "architecture": {
184
- "components": [
185
- {"name": "API Server", "type": "service", "tech": "Express.js", "files": ["src/server.ts"]},
186
- {"name": "PostgreSQL", "type": "database", "tech": "Prisma", "files": ["prisma/schema.prisma"]},
187
- {"name": "Redis", "type": "cache", "tech": "ioredis", "files": ["src/redis.ts"]}
188
- ],
189
- "trustBoundaries": [
190
- {"name": "Client → API", "from": "Browser", "to": "API Server", "protocol": "HTTPS"},
191
- {"name": "API → DB", "from": "API Server", "to": "PostgreSQL", "protocol": "TLS"}
192
- ],
193
- "externalDependencies": [
194
- {"name": "Stripe", "type": "payment", "files": ["src/payments/stripe.ts"]},
195
- {"name": "OpenAI", "type": "ai", "files": ["src/ai/openai.ts"]}
196
- ],
197
- "criticalAssets": [
198
- {"name": "User Credentials", "location": "PostgreSQL", "protection": "bcrypt"},
199
- {"name": "API Keys", "location": "Environment", "protection": "Secrets Manager"}
200
- ]
201
- },
202
- "detectedTechnologies": {
203
- "hasAI": true,
204
- "hasRedis": true,
205
- "hasEnclave": false,
206
- "hasDatabase": true,
207
- "databaseType": "PostgreSQL"
208
- }
209
- }
210
- ```
211
-
212
- **This architecture map is used by:**
213
- - All scanners to understand context
214
- - EXEC agent for executive summary
215
- - Final report for architecture overview
216
-
217
- ---
218
-
219
- ## CRITICAL OUTPUT FORMAT
220
-
221
- Every finding MUST include ALL these fields for the report to work:
222
-
223
- ```json
224
- {
225
- "id": "PREFIX-XXX",
226
- "title": "Descriptive title specific to the exact vulnerability (NOT generic category labels)",
227
- "severity": "critical|high|medium|low|info",
228
- "category": "Category name",
229
- "file": "exact/path/to/file.ts",
230
- "line": 123,
231
- "endLine": 156,
232
- "code": "the vulnerable/problematic code snippet",
233
- "description": "Precise technical narrative: what function has the issue, how it manifests, why it's dangerous. Include DREAD-D score inline for HIGH/CRITICAL.",
234
- "impact": "Security impact - what an attacker could exploit, potential damage, real-world risk",
235
- "attackChain": "Step-by-step exploitation: 1. Attacker does X, 2. System responds with Y, 3. Attacker gains Z",
236
- "recommendation": "Immediately actionable: specific function names, specific patterns, specific code changes",
237
- "cwe": "CWE-XXX (if applicable)",
238
- "confidence": 85,
239
- "fixOwner": "developer|devops|architect",
240
- "fixType": "code|config|infrastructure|design",
241
- "crossReferences": ["OTHER-ID-1"],
242
- "dread": {
243
- "damage": 8,
244
- "reproducibility": 9,
245
- "exploitability": 7,
246
- "affectedUsers": 10,
247
- "discoverability": 6,
248
- "score": 8.0
249
- }
250
- }
251
- ```
252
-
253
- ### fixOwner & fixType Guidelines
254
-
255
- **fixOwner** - Who should fix this:
256
- - `developer` - Code change required (validation, sanitization, logic fix)
257
- - `devops` - Infrastructure/config change (NetworkPolicy, firewall, K8s config, CI/CD)
258
- - `architect` - Design decision needed (authentication strategy, data flow, service boundaries)
259
-
260
- **fixType** - What kind of fix:
261
- - `code` - Change application code
262
- - `config` - Change configuration files (env, yaml, json)
263
- - `infrastructure` - Change deployment/infra (K8s, Docker, cloud)
264
- - `design` - Requires architectural redesign
265
-
266
- ## DREAD SCORING (for HIGH and CRITICAL findings)
267
-
268
- Calculate DREAD score (1-10 for each, average for final score):
269
-
270
- - **Damage**: How severe is the impact? (10 = full system compromise, 1 = minimal)
271
- - **Reproducibility**: How easy to reproduce? (10 = always works, 1 = rare conditions)
272
- - **Exploitability**: How easy to exploit? (10 = script kiddie, 1 = expert + physical access)
273
- - **Affected Users**: How many users impacted? (10 = all users, 1 = single admin)
274
- - **Discoverability**: How easy to find? (10 = obvious, 1 = requires source code)
275
-
276
- **Score interpretation**:
277
- - 9.0-10.0 = CRITICAL (exploit immediately)
278
- - 7.0-8.9 = HIGH (fix within days)
279
- - 5.0-6.9 = MEDIUM (fix within sprint)
280
- - 3.0-4.9 = LOW (backlog)
281
- - 1.0-2.9 = INFO (document only)
282
-
283
- ## PROFESSIONAL WRITING STANDARDS
284
-
285
- **Every finding must read as if written by an experienced security consultant, not a generic scanner.**
286
-
287
- ### Title Quality
288
- Titles must be descriptive and specific to the exact vulnerability — not generic category labels.
289
-
290
- **BAD (generic):**
291
- - "Hardcoded credentials found"
292
- - "Missing input validation"
293
- - "XSS vulnerability"
294
-
295
- **GOOD (descriptive, specific to the code):**
296
- - "Hardcoded Tracker API Keys and Hash Salts in Helm Values"
297
- - "Attestation Fallback Accepts Unverified Enclave Keys"
298
- - "Credit Deduction After GPU Processing in Non-Streaming Path"
299
- - "Command Injection via Unvalidated Model Name in pm2 delete"
300
-
301
- ### Description Quality
302
- Descriptions must trace the exact technical flow: what function, what input, what happens, and what the consequence is — in ONE precise paragraph.
303
-
304
- **BAD (vague):**
305
- "There is a security issue with hardcoded credentials in the configuration file. This could allow unauthorized access."
306
-
307
- **GOOD (precise technical narrative):**
308
- "Staging and production Helm values contain hardcoded API keys (stg-tracker-api-key, prd-tracker-api-key) and hash salts in plaintext, committed to version control. Anyone with repo access can write arbitrary data to the tracker. DREAD-D: 6.5."
309
-
310
- **GOOD (traces the full attack flow):**
311
- "When the attestation bundle endpoint is unavailable, fetchEnclaveInfo() falls back to the legacy /api/v1/enclave endpoint and stores keys with keysVerified: false. The browser silently proceeds to encrypt messages with public keys that have not been cryptographically bound to hardware attestation — enabling a man-in-the-middle attack by a compromised gateway."
312
-
313
- **GOOD (explains business logic flaw):**
314
- "In the non-streaming path, credit deduction happens after the enclave has processed the request. A concurrent request could deplete credits between the pre-flight check and the deduction, consuming GPU resources without payment. The streaming path handles this correctly."
315
-
316
- ### Recommendation Quality
317
- Recommendations must be immediately actionable — specific function names, specific patterns, specific code.
318
-
319
- **BAD:**
320
- "Fix the hardcoded credentials"
321
- "Add input validation"
322
-
323
- **GOOD:**
324
- "Move to AWS Secrets Manager alongside existing KP_SECRETS_PATH pattern. Remove from version control. Rotate immediately."
325
- "Extract to trackRedisMetrics(redis, models, userIdentifier) and call from both paths."
326
- "Move validation to the top of startModels(). Apply in stopModels(). Use execFileAsync('pm2', ['delete', model])."
327
- "Validate against whitelist from models.json or restrict to ^[a-zA-Z0-9_-]+$."
328
-
329
- ### Cross-Referencing
330
- When multiple agents identify the same issue from different perspectives, MERGE them using dual IDs:
331
- - "CR-02 / T-EKS-3: Hardcoded Tracker API Keys and Hash Salts in Helm Values"
332
- - "T-EKS-4 / CR-18: User Identity Logged and Hash Truncated to 64 Bits"
333
- - "T-BFF-3 / CR-08: Error Details Leaked to Clients"
334
-
335
- This shows the issue was found independently from multiple angles, increasing confidence.
336
-
337
- ### Quantitative Precision
338
- Always include specific numbers when available:
339
- - Line counts: "160 lines of Redis metrics tracking code is duplicated verbatim"
340
- - Percentages: "5.3% of the codebase"
341
- - Bit lengths: "truncates SHA-256 to only 16 hex characters (64 bits)"
342
- - Specific values: "session timeout of 24h", "maxAge: 31536000"
343
-
344
- ### DREAD Score Inline
345
- For HIGH and CRITICAL findings, include the DREAD-D score directly in the description text: "DREAD-D: 6.3."
346
-
347
- ### Positive Observations Depth
348
- Positive observations must cite specific technical evidence, not generic praise.
349
-
350
- **BAD:**
351
- "Good authentication implementation"
352
-
353
- **GOOD:**
354
- "Zero-Knowledge Architecture — EKS gateway genuinely never sees plaintext. Encrypted payloads flow through without decryption. Well-enforced across all components."
355
- "Atomic Credit Operations — Lua scripts for token burning and balance deduction prevent cross-pod race conditions. Check-and-deduct is atomic."
356
- "Secure File Handling — MIME + magic number validation, memory-only storage, size limits. secureDeleteFile() overwrites with random data before deletion."
357
-
358
- ---
359
-
360
- ## FIELD GUIDELINES
361
-
362
- ### description (REQUIRED — PROFESSIONAL QUALITY)
363
- Write a precise technical narrative explaining:
364
- 1. **What** specific function/file/pattern has the issue
365
- 2. **How** the vulnerability manifests (trace the data flow)
366
- 3. **Why** it's dangerous (the consequence in one clause)
367
- 4. Include DREAD-D score inline for HIGH/CRITICAL: "DREAD-D: 6.5."
368
-
369
- ### impact (REQUIRED)
370
- Explain the real-world security impact. Be specific about:
371
- - What an attacker could do (e.g., "steal session tokens", "access other users' data")
372
- - The potential damage (e.g., "full account takeover", "data breach")
373
- - Why this matters to the business (e.g., "regulatory compliance violation", "reputation damage")
374
-
375
- Example: "An attacker could inject malicious scripts that steal session cookies, enabling full account takeover of any logged-in user"
376
-
377
- ### recommendation (REQUIRED — ACTIONABLE)
378
- Must include at least one of:
379
- - Specific function/method name to create or modify
380
- - Specific configuration change with exact values
381
- - Specific library/pattern to use
382
- - Code snippet showing the fix
383
-
384
- ---
385
-
386
- ## PHASE 1: PARALLEL DISCOVERY
387
-
388
- Launch ALL discovery agents simultaneously.
389
-
390
- **IMPORTANT: Each agent MUST follow these steps:**
391
-
392
- 1. **Create output directory**: `mkdir -p .coverme/agents`
393
- 2. **Scan the codebase** according to agent-specific instructions
394
- 3. **Save findings to file**: `.coverme/agents/{AGENT_ID}.json`
395
- 4. **Return ONLY status**: `{"status": "complete", "file": ".coverme/agents/{AGENT_ID}.json", "count": N}`
396
-
397
- **Agent output file template:**
398
- ```json
399
- {
400
- "agentId": "SEC",
401
- "agentName": "Security Core Scanner",
402
- "scanDate": "{{SCAN_DATE}}",
403
- "skipped": false,
404
- "skipReason": null,
405
- "findings": [/* array of findings */],
406
- "positives": [/* array of positive observations */]
407
- }
408
- ```
409
-
410
- **For CONDITIONAL agents (AI, REDIS, ENC, DB):**
411
- - First detect if relevant code exists
412
- - If NOT found: `{"skipped": true, "skipReason": "No AI/LLM code detected", "findings": []}`
413
- - If found: proceed with normal scan
414
-
415
- ---
416
-
417
- ### AGENT 1: Security Core Scanner (ID prefix: SEC)
418
-
419
- Scan {{PROJECT_PATH}} for OWASP Top 10 and core security vulnerabilities.
420
-
421
- CHECK FOR:
422
- - SQL/NoSQL Injection (parameterized queries missing)
423
- - XSS (reflected, stored, DOM-based)
424
- - Command Injection (shell commands with user input)
425
- - Path Traversal (../ in file operations)
426
- - SSRF (user-controlled URLs in fetch/axios)
427
- - XXE (XML parsing without disabling entities)
428
- - Insecure Deserialization (JSON.parse on untrusted data)
429
- - Hardcoded Secrets (API keys, passwords, tokens in code)
430
- - Weak Cryptography (MD5, SHA1 for passwords, ECB mode)
431
- - Insecure Random (Math.random for security purposes)
432
-
433
- **DATABASE-SPECIFIC DANGEROUS FUNCTIONS** (check for ANY database):
434
- - DuckDB: read_text(), read_blob(), read_csv_auto(), read_parquet(), glob(), getenv(), httpfs
435
- - SQLite: load_extension(), readfile(), writefile()
436
- - PostgreSQL: pg_read_file(), pg_ls_dir(), COPY TO/FROM
437
- - MySQL: LOAD_FILE(), INTO OUTFILE, INTO DUMPFILE
438
- - MongoDB: $where with user input, mapReduce with user functions
439
- - Redis: EVAL/EVALSHA with user input, CONFIG, DEBUG commands
440
-
441
- **BLOCKLIST BYPASS PATTERNS**:
442
- - Keyword blocklists that miss database-specific functions
443
- - Case sensitivity bypass (READ_TEXT vs read_text)
444
- - Unicode homoglyph bypass
445
- - Comment injection (SELECT/**/read_text)
446
- - Encoding bypass (hex, base64, URL encoding)
447
-
448
- For EACH finding, output the FULL JSON format above.
449
-
450
- ---
451
-
452
- ### AGENT 2: Auth & Session Scanner (ID prefix: AUTH)
453
-
454
- Scan {{PROJECT_PATH}} for authentication and session vulnerabilities.
455
-
456
- **FIRST: Detect which auth method(s) this project uses:**
457
-
458
- | Auth Type | Detection Pattern |
459
- |-----------|-------------------|
460
- | OAuth/OIDC | `oauth`, `oidc`, `authorization_code`, `client_id`, `redirect_uri` |
461
- | JWT | `jsonwebtoken`, `jwt`, `Bearer`, `accessToken`, `refreshToken` |
462
- | Session-based | `express-session`, `cookie-session`, `session.save`, `req.session` |
463
- | API Keys | `x-api-key`, `apiKey`, `api_key`, `API_SECRET` |
464
- | Basic Auth | `Basic `, `Authorization`, `btoa`, `base64` |
465
- | Clerk | `@clerk`, `useAuth`, `clerkMiddleware` |
466
- | Auth0 | `@auth0`, `auth0-js`, `auth0-react` |
467
- | Firebase Auth | `firebase/auth`, `signInWith`, `onAuthStateChanged` |
468
- | Passport.js | `passport`, `passport-local`, `passport-jwt` |
469
- | Supabase Auth | `@supabase/auth`, `supabase.auth` |
470
- | NextAuth | `next-auth`, `NextAuth`, `getServerSession` |
471
- | Custom | `login`, `authenticate`, `verifyToken`, `checkAuth` |
472
-
473
- **FOR EACH AUTH TYPE DETECTED, check specific vulnerabilities:**
474
-
475
- **OAuth/OIDC:**
476
- - Open redirect in return_url/redirect_uri (CRITICAL!)
477
- - State parameter missing or predictable
478
- - PKCE not implemented for public clients
479
- - Token stored in localStorage (XSS vulnerable)
480
- - Refresh token rotation missing
481
- - ID token validation incomplete
482
-
483
- **JWT:**
484
- - `alg: none` accepted (signature bypass)
485
- - Weak secret (< 256 bits)
486
- - No expiry (`exp` claim missing)
487
- - Secret in code/env without rotation
488
- - `HS256` when `RS256` needed (shared secret risk)
489
- - Token not invalidated on logout
490
-
491
- **Session-based:**
492
- - Session ID in URL (referer leak)
493
- - Session not invalidated on logout
494
- - Session timeout too long (>24h)
495
- - Session fixation (not regenerated after login)
496
- - Session data not encrypted
497
- - Missing `secure`, `httpOnly`, `sameSite` on cookies
498
-
499
- **API Keys:**
500
- - API key in URL (logged, cached, referer leak)
501
- - No key rotation mechanism
502
- - Same key for all environments
503
- - Key logged or in error messages
504
- - No per-key rate limiting
505
-
506
- **Password/Credentials:**
507
- - Password reset: predictable tokens
508
- - Password reset: no expiry
509
- - No rate limiting on login
510
- - User enumeration via different responses
511
- - Passwords stored without hashing
512
- - Weak password policy
513
-
514
- **UNIVERSAL AUTH CHECKS (all types):**
515
- - Brute force protection missing
516
- - MFA bypass paths
517
- - Account lockout not implemented
518
- - Auth state not cleared on logout
519
- - Sensitive endpoints without auth
520
-
521
- **MEMORY SAFETY FOR SECRETS**:
522
- - Cryptographic keys not zeroed after use
523
- - Passwords stored in String instead of char[]
524
- - Session tokens not cleared on logout
525
- - Private keys in JavaScript objects (V8 heap)
526
-
527
- **TIMING ATTACKS**:
528
- - Non-constant-time string comparison for tokens/secrets
529
- - Early return on auth failure leaking valid usernames
530
- - Different response times for valid vs invalid credentials
531
-
532
- For EACH finding, output the FULL JSON format.
533
-
534
- ---
535
-
536
- ### AGENT 3: API Security Scanner (ID prefix: API)
537
-
538
- Scan {{PROJECT_PATH}} for API security issues.
539
-
540
- CHECK FOR:
541
- - Missing authentication on endpoints
542
- - Broken authorization (IDOR, privilege escalation)
543
- - Input validation missing (Zod/Joi schemas)
544
- - Rate limiting issues (non-atomic INCR+EXPIRE in Redis)
545
- - CORS misconfiguration (Access-Control-Allow-Origin: *)
546
- - Mass assignment (spreading req.body into DB)
547
- - Webhook signature verification missing (HMAC)
548
- - GraphQL introspection enabled in production
549
- - API versioning issues
550
- - Excessive data exposure in responses
551
-
552
- **CORS MISCONFIGURATION** (MEDIUM):
553
- Look for these vulnerable patterns:
554
- ```javascript
555
- // VULNERABLE - reflects ANY origin
556
- res.header('Access-Control-Allow-Origin', req.headers.origin);
557
- res.header('Access-Control-Allow-Origin', '*');
558
-
559
- // VULNERABLE - no whitelist validation
560
- app.use(cors({ origin: true }));
561
- ```
562
- Only mark as safe if there's explicit whitelist validation:
563
- ```javascript
564
- const allowedOrigins = ['https://app.example.com'];
565
- if (allowedOrigins.includes(origin)) { ... }
566
- ```
567
-
568
- **HELMET MISCONFIGURATION** (MEDIUM):
569
- ```javascript
570
- app.use(helmet()); // Using defaults only - INSUFFICIENT!
571
- ```
572
- Check that helmet() includes:
573
- - Custom `contentSecurityPolicy` with proper directives
574
- - `hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }`
575
- - Proper `referrerPolicy`
576
- Report as MEDIUM if using only defaults without customization.
577
-
578
- **FAIL-OPEN vs FAIL-CLOSED PATTERNS** (CRITICAL):
579
- - IP whitelist empty/missing = allow all (should deny all)
580
- - Auth middleware errors = request passes through (should block)
581
- - Rate limiter Redis down = no limiting (should block or use fallback)
582
- - Config missing = insecure defaults (should fail startup)
583
- - Feature flag missing = feature enabled (should be disabled)
584
- - RBAC role not found = access granted (should deny)
585
-
586
- Look for patterns like:
587
- ```
588
- if (whitelist.length > 0) { check() } // FAIL-OPEN: empty whitelist bypasses
589
- if (!config.AUTH_REQUIRED) { next() } // FAIL-OPEN: missing config = no auth
590
- catch(e) { next() } // FAIL-OPEN: error = proceed
591
- ```
592
-
593
- **ADMIN/INTERNAL API EXPOSURE**:
594
- - Admin APIs bound to 0.0.0.0 instead of 127.0.0.1
595
- - Internal ports exposed without auth
596
- - Debug endpoints in production
597
- - Metrics/health endpoints exposing sensitive data
598
-
599
- For EACH finding, output the FULL JSON format.
600
-
601
- ---
602
-
603
- ### AGENT 4: Infrastructure Scanner (ID prefix: INFRA)
604
-
605
- Scan {{PROJECT_PATH}} for infrastructure and DevOps issues.
606
-
607
- CHECK FOR:
608
- - Secrets in git-tracked files (Helm values, K8s manifests, .env committed)
609
- - Real IPs/hostnames committed to repo
610
- - Docker issues (running as root, secrets in layers)
611
- - K8s pod security context missing
612
- - CI/CD pipeline security (missing quality gates)
613
- - Missing security headers in server config
614
- - TLS/SSL configuration issues
615
- - Debug mode enabled in production configs
616
- - Exposed internal ports
617
- - Missing resource limits
618
-
619
- **SECRETS IN CONFIGURATION FILES** (check ALL config formats):
620
- - Helm values.yaml / values-*.yaml with hardcoded secrets
621
- - Kubernetes secrets not using external secrets manager
622
- - Docker Compose with hardcoded passwords
623
- - Terraform tfvars with credentials
624
- - Ansible vault passwords in plaintext
625
- - CI/CD pipeline secrets in yaml files (.github/workflows, .gitlab-ci.yml)
626
-
627
- **SECRETS IN GIT HISTORY** (CRITICAL CHECK!):
628
- Run these commands to check if secrets were EVER committed:
629
- ```bash
630
- git log --all --full-history -- "**/secrets*" "**/credentials*" "**/*.env"
631
- git log --all -p -S "AWS_SECRET" -S "PRIVATE_KEY" --source
632
- ```
633
- If secrets appear in history, they are EXPOSED even if now gitignored!
634
-
635
- **PRIVILEGE ESCALATION RISKS**:
636
- - Containers/processes running as root
637
- - Missing securityContext in K8s (runAsNonRoot, readOnlyRootFilesystem)
638
- - Privileged containers
639
- - Host path mounts to sensitive directories
640
- - Missing capability drops (drop: ALL)
641
- - Service accounts with excessive permissions
642
-
643
- **CONFIGURATION THAT SHOULD FAIL AT STARTUP**:
644
- - Required environment variables not validated at startup
645
- - Missing config = silent fallback to insecure defaults
646
- - No validation of secret strength/format at startup
647
-
648
- **DEPENDENCY SECURITY** (HIGH if missing):
649
- Check for presence of:
650
- - `npm audit` or `yarn audit` in CI pipeline
651
- - Dependabot/Renovate configuration (.github/dependabot.yml, renovate.json)
652
- - SBOM generation (cyclonedx, syft)
653
- - Snyk/Trivy/Grype scanning
654
- Report as HIGH if NONE of these exist - supply chain risk!
655
-
656
- **LOGGING & MONITORING**:
657
- - Log rotation configured? (maxFiles, maxsize in Winston/Pino)
658
- - Log retention policy defined?
659
- - Sensitive data redacted from logs?
660
- Report as LOW if log rotation missing - disk exhaustion risk.
661
-
662
- For EACH finding, output the FULL JSON format.
663
-
664
- ---
665
-
666
- ### AGENT 5: Data & Privacy Scanner (ID prefix: DATA)
667
-
668
- Scan {{PROJECT_PATH}} for data protection and privacy issues.
669
-
670
- CHECK FOR:
671
- - PII logging (emails, IPs, names in logs)
672
- - GDPR deletion bugs (incomplete data removal)
673
- - Encryption at rest missing for sensitive fields
674
- - Data residency violations
675
- - Backup encryption missing
676
- - Sensitive data in URLs/query params
677
- - Missing data classification
678
- - Retention policy not enforced
679
- - Export functionality exposing too much data
680
- - Cross-tenant data leakage
681
-
682
- For EACH finding, output the FULL JSON format.
683
-
684
- ---
685
-
686
- ### AGENT 6: AI/LLM Security Scanner (ID prefix: AI)
687
-
688
- **CONDITIONAL AGENT** - First detect if this project uses AI/LLM:
689
-
690
- ```bash
691
- # Search for AI/LLM indicators
692
- grep -r -l "openai\|anthropic\|langchain\|ollama\|huggingface\|llama\|gpt-\|claude\|gemini\|bedrock\|vertex" --include="*.ts" --include="*.js" --include="*.py" --include="*.json" .
693
- ```
694
-
695
- **IF NO AI CODE FOUND**: Output and skip:
696
- ```json
697
- {"skipped": true, "reason": "No AI/LLM code detected in project", "findings": []}
698
- ```
699
-
700
- **IF AI CODE FOUND**: Scan {{PROJECT_PATH}} for AI/LLM specific vulnerabilities.
701
-
702
- CHECK FOR:
703
- - Prompt injection (user input directly in prompts)
704
- - Content filter fail-open (errors bypass safety)
705
- - CDN imports without SRI (integrity hashes missing)
706
- - Model output not sanitized before use
707
- - Sensitive data sent to external AI APIs
708
- - AI decision logging insufficient for audit
709
- - Rate limiting on AI endpoints
710
- - Cost controls missing
711
- - Jailbreak prevention missing
712
- - PII in training data/prompts
713
-
714
- **LLM OUTPUT → CODE EXECUTION CHAINS**:
715
- - LLM generates SQL that gets executed (SQL injection via prompt injection)
716
- - LLM generates code that gets eval'd
717
- - LLM generates shell commands that get executed
718
- - LLM generates file paths that get accessed
719
- - LLM output used in template rendering (SSTI)
720
-
721
- **VALIDATION OF LLM OUTPUT**:
722
- - Is there ANY validation between LLM output and dangerous operations?
723
- - Are blocklists/allowlists applied to LLM-generated content?
724
- - Can the blocklist be bypassed? (check for completeness)
725
- - Is validation case-insensitive?
726
- - Does validation handle encoded input?
727
-
728
- **PROMPT SANITIZATION WEAKNESSES**:
729
- - Regex-based filtering (easily bypassed with synonyms, encoding, whitespace)
730
- - Literal string matching (bypass with Unicode homoglyphs)
731
- - Missing: base64 encoded payloads, ROT13, leetspeak variations
732
-
733
- For EACH finding, output the FULL JSON format.
734
-
735
- ---
736
-
737
- ### AGENT 7: Performance & DoS Scanner (ID prefix: PERF)
738
-
739
- Scan {{PROJECT_PATH}} for performance and denial-of-service issues.
740
-
741
- CHECK FOR:
742
- - N+1 query patterns
743
- - ReDoS (regex denial of service)
744
- - Memory leaks (event listeners not removed, growing caches)
745
- - Unbounded data structures
746
- - Missing pagination
747
- - SSE/WebSocket buffering entire streams
748
- - Heavy computation blocking event loop
749
- - Missing connection pooling
750
- - Resource exhaustion (no limits on uploads, requests)
751
- - Synchronous operations that should be async
752
-
753
- **DANGEROUS DATABASE OPERATIONS IN HOT PATHS**:
754
- - Redis KEYS command (blocks entire server, O(n) scan)
755
- - MongoDB find() without limit
756
- - SQL SELECT without LIMIT on large tables
757
- - Full table scans in request handlers
758
- - Aggregations without indexes
759
-
760
- **BLOCKING OPERATIONS**:
761
- - Synchronous file I/O in request handlers
762
- - crypto.pbkdf2Sync / crypto.scryptSync in hot paths
763
- - JSON.parse on unbounded input
764
- - Regex on user input without timeout
765
- - DNS lookups without caching
766
-
767
- For EACH finding, output the FULL JSON format.
768
-
769
- ---
770
-
771
- ### AGENT 8: Business Logic Scanner (ID prefix: BIZ)
772
-
773
- Scan {{PROJECT_PATH}} for business logic vulnerabilities.
774
-
775
- CHECK FOR:
776
- - Race conditions (TOCTOU, double-spend)
777
- - Workflow bypass (skipping required steps)
778
- - Price/quantity manipulation
779
- - Negative value attacks
780
- - State machine violations
781
- - Time-based attacks (timing side channels)
782
- - Non-constant-time comparisons for secrets
783
- - Duplicate request handling (missing idempotency)
784
- - Business rule bypass
785
- - Inconsistent validation between client/server
786
-
787
- For EACH finding, output the FULL JSON format.
788
-
789
- ---
790
-
791
- ### AGENT 9: Code Quality Scanner (ID prefix: QUAL)
792
-
793
- Scan {{PROJECT_PATH}} for code quality issues that affect security/reliability.
794
-
795
- CHECK FOR:
796
- - Error handling swallowing exceptions silently
797
- - Missing error boundaries
798
- - Inconsistent error responses
799
- - Dead code with security implications
800
- - DRY violations in security code
801
- - Complex functions (high cyclomatic complexity)
802
- - Any/unknown types masking issues
803
- - Missing null checks
804
- - Callback hell making auditing hard
805
- - Anti-patterns (god objects, tight coupling)
806
-
807
- **DEAD CODE WITH SECURITY IMPLICATIONS** (CRITICAL):
808
- - Old/commented code that has BETTER security than current code
809
- - Deprecated functions with security controls not ported to replacement
810
- - Legacy validation code that was more thorough
811
- - Backup implementations with different (better) security model
812
- - TODO/FIXME comments about security issues never addressed
813
-
814
- Look for patterns:
815
- - `// OLD: validated input here` followed by code that doesn't
816
- - Functions named `*_secure`, `*_safe`, `*_v2` that are unused
817
- - Commented-out security checks with no explanation
818
- - Multiple implementations where one is more secure but unused
819
-
820
- **SECURITY-CRITICAL CODE WITHOUT TESTS**:
821
- - Authentication/authorization code with 0% test coverage
822
- - Input validation functions without unit tests
823
- - Cryptographic operations without test vectors
824
- - Rate limiting logic without integration tests
825
-
826
- For EACH finding, output the FULL JSON format.
827
-
828
- ---
829
-
830
- ### AGENT 10: Testing & Reliability Scanner (ID prefix: TEST)
831
-
832
- Scan {{PROJECT_PATH}} for testing and reliability gaps.
833
-
834
- CHECK FOR:
835
- - Missing tests for security-critical paths
836
- - No CI quality gates
837
- - Missing health checks
838
- - No graceful shutdown handling
839
- - Circuit breakers missing
840
- - Retry logic without exponential backoff
841
- - Missing observability (logging, metrics, tracing)
842
- - Feature flags without cleanup
843
- - Database migrations without rollback
844
- - No chaos/failure testing evidence
845
-
846
- For EACH finding, output the FULL JSON format.
847
-
848
- ---
849
-
850
- ### AGENT 11: Redis & Cache Security Scanner (ID prefix: REDIS)
851
-
852
- **CONDITIONAL AGENT** - First detect if this project uses Redis/Cache:
853
-
854
- ```bash
855
- # Search for Redis/Cache indicators
856
- grep -r -l "redis\|ioredis\|memcached\|node-cache\|lru-cache\|cache-manager" --include="*.ts" --include="*.js" --include="*.json" --include="*.yaml" .
857
- ```
858
-
859
- **IF NO CACHE CODE FOUND**: Output and skip:
860
- ```json
861
- {"skipped": true, "reason": "No Redis/Cache code detected in project", "findings": []}
862
- ```
863
-
864
- **IF CACHE CODE FOUND**: Scan {{PROJECT_PATH}} for Redis, Memcached, and cache-related security issues.
865
-
866
- **REDIS SECURITY:**
867
-
868
- **DANGEROUS COMMANDS:**
869
- - `KEYS *` in production code (blocks entire server, use SCAN instead)
870
- - `FLUSHALL`, `FLUSHDB` accessible without protection
871
- - `DEBUG`, `CONFIG` commands enabled in production
872
- - `EVAL`/`EVALSHA` with user-controlled scripts (Lua injection)
873
- - `MIGRATE` command enabled (data exfiltration risk)
874
-
875
- **AUTHENTICATION & ACCESS:**
876
- - Redis without AUTH (requirepass not set)
877
- - Redis exposed on 0.0.0.0 instead of 127.0.0.1
878
- - Missing ACL configuration (Redis 6+)
879
- - Default port 6379 exposed externally
880
- - Missing TLS for Redis connections
881
- - Connection strings with passwords in code/logs
882
-
883
- **DATA SECURITY:**
884
- - Sensitive data stored without encryption
885
- - PII in Redis without TTL (data retention violation)
886
- - Session data without proper expiration
887
- - Cache keys predictable/enumerable (info disclosure)
888
- - No key prefix separation between tenants (multi-tenant leak)
889
-
890
- **RACE CONDITIONS:**
891
- - Non-atomic read-modify-write patterns
892
- - Missing WATCH/MULTI/EXEC for transactions
893
- - INCR + EXPIRE not atomic (use SET with NX and EX)
894
- - Distributed locks without proper implementation (SETNX issues)
895
-
896
- **MEMORY & DoS:**
897
- - No maxmemory configuration
898
- - No eviction policy (maxmemory-policy)
899
- - Unbounded lists/sets that can grow infinitely
900
- - Missing key expiration (TTL) for temporary data
901
- - Pub/Sub without subscriber limits
902
-
903
- **SERIALIZATION:**
904
- - Pickle/Marshal deserialization from Redis (RCE risk)
905
- - JSON parsing without validation
906
- - Protobuf/MessagePack without schema validation
907
-
908
- Example finding:
909
- ```json
910
- {
911
- "id": "REDIS-001",
912
- "title": "Redis KEYS command used in production",
913
- "severity": "high",
914
- "fixOwner": "developer",
915
- "fixType": "code",
916
- "file": "src/cache/redis.ts",
917
- "line": 45,
918
- "code": "await redis.keys('user:*')",
919
- "description": "KEYS command blocks the entire Redis server. With large datasets this can cause seconds of downtime.",
920
- "recommendation": "Use SCAN with cursor-based iteration instead: `for await (const key of redis.scanIterator({ MATCH: 'user:*' }))`"
921
- }
922
- ```
923
-
924
- For EACH finding, output the FULL JSON format.
925
-
926
- ---
927
-
928
- ### AGENT 12: Resilience & Fallback Scanner (ID prefix: RESIL)
929
-
930
- Scan {{PROJECT_PATH}} for resilience patterns and fallback mechanisms.
931
-
932
- **CIRCUIT BREAKERS:**
933
- - External service calls without circuit breaker
934
- - Circuit breaker without proper thresholds
935
- - No fallback when circuit is open
936
- - Missing health check for circuit recovery
937
- - Circuit breaker state not monitored/alerted
938
-
939
- **RETRY PATTERNS:**
940
- - Retries without exponential backoff
941
- - Retries without jitter (thundering herd)
942
- - Retries without max attempts limit
943
- - Retrying non-idempotent operations
944
- - No retry budget (retry storms)
945
-
946
- **TIMEOUTS:**
947
- - HTTP calls without timeout
948
- - Database queries without timeout
949
- - External API calls without timeout
950
- - Cascading timeouts not configured properly
951
- - Timeout longer than upstream caller's timeout
952
-
953
- **FALLBACKS:**
954
- - No fallback for critical external dependencies
955
- - Fallback that calls same failing service
956
- - Missing cached fallback data
957
- - No degraded mode implementation
958
- - Feature flags without fallback behavior
959
-
960
- **BULKHEADS:**
961
- - Single connection pool for all operations
962
- - No isolation between critical and non-critical paths
963
- - Thread/worker pool exhaustion possible
964
- - No request queuing limits
965
- - Missing backpressure handling
966
-
967
- **GRACEFUL DEGRADATION:**
968
- - All-or-nothing service behavior
969
- - No partial response capability
970
- - Missing feature flags for degradation
971
- - No read-only mode fallback
972
- - Essential vs non-essential features not separated
973
-
974
- **HEALTH CHECKS:**
975
- - Health check that calls external dependencies
976
- - No distinction between liveness and readiness
977
- - Health check timeout too short/long
978
- - Missing dependency health in readiness check
979
- - Health endpoint exposed without rate limiting
980
-
981
- Example finding:
982
- ```json
983
- {
984
- "id": "RESIL-001",
985
- "title": "External API call without circuit breaker",
986
- "severity": "medium",
987
- "fixOwner": "developer",
988
- "fixType": "code",
989
- "file": "src/services/payment.ts",
990
- "line": 78,
991
- "code": "await axios.post(paymentApi, data)",
992
- "description": "Payment API calls have no circuit breaker. If the API is slow/down, requests will pile up and exhaust resources.",
993
- "recommendation": "Wrap with circuit breaker: `const result = await circuitBreaker.fire(() => axios.post(...))`"
994
- }
995
- ```
996
-
997
- For EACH finding, output the FULL JSON format.
998
-
999
- ---
1000
-
1001
- ### AGENT 13: PII & Sensitive Data Scanner (ID prefix: PII)
1002
-
1003
- Scan {{PROJECT_PATH}} for PII exposure and sensitive data handling issues.
1004
-
1005
- **PII IN LOGS:**
1006
- - Email addresses logged
1007
- - Phone numbers logged
1008
- - IP addresses logged without justification
1009
- - Names/addresses in logs
1010
- - User IDs that can be linked to PII
1011
- - Request/response bodies logged without redaction
1012
- - Error messages containing PII
1013
-
1014
- **PII IN URLS:**
1015
- - PII in URL path (e.g., /user/john@email.com)
1016
- - PII in query parameters
1017
- - Session tokens in URLs (referer leak)
1018
- - Sensitive data in URL fragments
1019
-
1020
- **PII IN STORAGE:**
1021
- - PII stored without encryption at rest
1022
- - PII in plaintext in database
1023
- - PII in local storage/session storage (browser)
1024
- - PII in cookies without encryption
1025
- - Backup data containing unencrypted PII
1026
-
1027
- **PII IN TRANSIT:**
1028
- - PII sent over non-HTTPS connections
1029
- - PII in WebSocket without TLS
1030
- - PII in email notifications (plaintext)
1031
- - PII passed to third-party services without DPA
1032
-
1033
- **PII RETENTION:**
1034
- - No TTL on PII data
1035
- - No data deletion mechanism
1036
- - Soft delete keeping PII accessible
1037
- - Audit logs retaining PII indefinitely
1038
- - Analytics containing raw PII
1039
-
1040
- **GDPR/CCPA COMPLIANCE:**
1041
- - No data export functionality
1042
- - No data deletion on request
1043
- - Missing consent tracking
1044
- - No purpose limitation enforcement
1045
- - PII shared without consent
1046
-
1047
- **SENSITIVE DATA TYPES TO FIND:**
1048
- - SSN, passport numbers, national IDs
1049
- - Credit card numbers (even partial)
1050
- - Bank account numbers
1051
- - Health/medical information
1052
- - Biometric data
1053
- - Location data (precise GPS)
1054
- - Authentication credentials
1055
- - API keys/tokens
1056
-
1057
- **DETECTION PATTERNS:**
1058
- ```
1059
- email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/
1060
- phone: /(\+\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}/
1061
- ssn: /\d{3}[-]?\d{2}[-]?\d{4}/
1062
- credit_card: /\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}/
1063
- ip_address: /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
1064
- ```
1065
-
1066
- For EACH finding, output the FULL JSON format.
1067
-
1068
- ---
1069
-
1070
- ### AGENT 14: Dead Code & Unused Scanner (ID prefix: DEAD)
1071
-
1072
- Scan {{PROJECT_PATH}} for dead code, unused dependencies, and technical debt.
1073
-
1074
- **UNUSED CODE:**
1075
- - Functions never called
1076
- - Classes never instantiated
1077
- - Variables assigned but never read
1078
- - Exported functions with no importers
1079
- - Event handlers never triggered
1080
- - API endpoints not used by any client
1081
-
1082
- **COMMENTED CODE:**
1083
- - Large blocks of commented-out code
1084
- - TODO/FIXME comments older than 6 months
1085
- - "Temporary" code that became permanent
1086
- - Debug code left in production
1087
- - Console.log/print statements
1088
-
1089
- **UNUSED DEPENDENCIES:**
1090
- - npm/pip packages installed but never imported
1091
- - Devdependencies in production bundle
1092
- - Duplicate dependencies (different versions)
1093
- - Dependencies imported but functions not used
1094
- - Polyfills for supported browser versions
1095
-
1096
- **UNREACHABLE CODE:**
1097
- - Code after return/throw/break
1098
- - Conditions that are always true/false
1099
- - Switch cases that can never match
1100
- - Error handlers that can never trigger
1101
- - Feature flags that are always on/off
1102
-
1103
- **DEAD FEATURE FLAGS:**
1104
- - Feature flags that are always enabled (remove flag)
1105
- - Feature flags that are always disabled (remove code)
1106
- - Feature flags with no owner
1107
- - A/B tests that concluded but weren't cleaned up
1108
-
1109
- **DEPRECATED PATTERNS:**
1110
- - Using deprecated APIs (with console warnings)
1111
- - Legacy code paths kept "just in case"
1112
- - Backward compatibility code for old versions
1113
- - Shims for removed features
1114
-
1115
- **SECURITY IMPLICATIONS:**
1116
- - Commented security checks (why removed?)
1117
- - Unused auth middleware (was security removed?)
1118
- - Dead validation code (security regression?)
1119
- - Unused rate limiting (intentional removal?)
1120
-
1121
- **TECHNICAL DEBT INDICATORS:**
1122
- - Files not modified in >2 years
1123
- - Code with "hack", "workaround", "temporary" comments
1124
- - Duplicate implementations of same logic
1125
- - Copy-pasted code blocks
1126
-
1127
- Example finding:
1128
- ```json
1129
- {
1130
- "id": "DEAD-001",
1131
- "title": "Unused npm dependency: lodash",
1132
- "severity": "low",
1133
- "fixOwner": "developer",
1134
- "fixType": "code",
1135
- "file": "package.json",
1136
- "line": 15,
1137
- "description": "lodash is listed as dependency but no imports found in codebase. Increases bundle size and potential security surface.",
1138
- "recommendation": "Remove with: npm uninstall lodash"
1139
- }
1140
- ```
1141
-
1142
- For EACH finding, output the FULL JSON format.
1143
-
1144
- ---
1145
-
1146
- ### AGENT 15: Database Security Scanner (ID prefix: DB)
1147
-
1148
- **AUTO-DETECT DATABASE TYPE(S)** - First identify which database(s) this project uses:
1149
-
1150
- | Database | Detection Pattern |
1151
- |----------|-------------------|
1152
- | PostgreSQL | `pg`, `postgres`, `@prisma`, `typeorm`, `knex`, `DATABASE_URL.*postgres` |
1153
- | MySQL | `mysql`, `mysql2`, `mariadb` |
1154
- | SQLite | `sqlite`, `better-sqlite3`, `sql.js` |
1155
- | MongoDB | `mongoose`, `mongodb`, `@mongo` |
1156
- | DynamoDB | `@aws-sdk/client-dynamodb`, `dynamodb`, `DocumentClient` |
1157
- | Redis | `redis`, `ioredis` |
1158
- | Elasticsearch | `@elastic`, `elasticsearch` |
1159
- | DuckDB | `duckdb`, `@duckdb` |
1160
- | Supabase | `@supabase/supabase-js`, `supabase`, `createClient.*supabase` |
1161
- | Prisma | `@prisma/client` |
1162
- | TypeORM | `typeorm`, `@Entity` |
1163
- | Sequelize | `sequelize` |
1164
- | Drizzle | `drizzle-orm` |
1165
- | PlanetScale | `@planetscale`, `planetscale` |
1166
- | Neon | `@neondatabase`, `neon` |
1167
- | Turso | `@libsql`, `turso` |
1168
-
1169
- **IF NO DATABASE FOUND**: Output and skip:
1170
- ```json
1171
- {"skipped": true, "reason": "No database code detected in project", "findings": []}
1172
- ```
1173
-
1174
- **IF DATABASE FOUND**: Scan for issues SPECIFIC to the detected database type(s).
1175
-
1176
- Scan {{PROJECT_PATH}} for database security issues across all database types.
1177
-
1178
- **SQL INJECTION (all SQL databases):**
1179
- - String concatenation in queries
1180
- - Template literals with user input in SQL
1181
- - Raw queries without parameterization
1182
- - Dynamic table/column names from user input
1183
- - ORDER BY with user-controlled column names
1184
- - LIMIT/OFFSET from unvalidated user input
1185
-
1186
- **NOSQL INJECTION:**
1187
- - MongoDB: $where with user input
1188
- - MongoDB: $regex with user-controlled patterns
1189
- - MongoDB: operator injection ({$gt: ""})
1190
- - DynamoDB: condition expressions with user input
1191
- - Elasticsearch: query string queries with user input
1192
-
1193
- **DANGEROUS DATABASE FUNCTIONS:**
1194
- ```
1195
- PostgreSQL: pg_read_file(), pg_ls_dir(), COPY TO/FROM, lo_import/export
1196
- MySQL: LOAD_FILE(), INTO OUTFILE, INTO DUMPFILE, LOAD DATA
1197
- SQLite: load_extension(), readfile(), writefile()
1198
- DuckDB: read_text(), read_blob(), read_csv_auto(), read_parquet(), glob(), httpfs
1199
- MongoDB: $where, mapReduce with user functions
1200
- Redis: EVAL with user scripts, CONFIG, DEBUG
1201
- ```
1202
-
1203
- **ACCESS CONTROL:**
1204
- - Database user with excessive privileges (GRANT ALL)
1205
- - Application using root/admin database user
1206
- - Same credentials for read and write operations
1207
- - No row-level security (RLS) for multi-tenant
1208
- - Missing column-level encryption for sensitive data
1209
-
1210
- **CONNECTION SECURITY:**
1211
- - Database connection without TLS/SSL
1212
- - Connection strings with credentials in code
1213
- - Connection pooling without limits
1214
- - No connection timeout configured
1215
- - Database exposed on public IP
1216
-
1217
- **QUERY PATTERNS:**
1218
- - SELECT * instead of specific columns
1219
- - No LIMIT on SELECT queries
1220
- - Missing indexes on filtered columns
1221
- - N+1 query patterns
1222
- - Full table scans in request handlers
1223
- - Unbounded JOINs
1224
-
1225
- **MIGRATIONS & SCHEMA:**
1226
- - Migrations without rollback capability
1227
- - Schema changes without backup
1228
- - Dropping columns with data
1229
- - Changing column types without data migration
1230
- - Foreign keys without ON DELETE policy
1231
-
1232
- **DATA INTEGRITY:**
1233
- - Missing foreign key constraints
1234
- - No unique constraints where needed
1235
- - Missing NOT NULL on required fields
1236
- - No CHECK constraints for data validation
1237
- - Orphan records possible
1238
-
1239
- **BACKUP & RECOVERY:**
1240
- - No backup configuration found
1241
- - Backups not encrypted
1242
- - No point-in-time recovery capability
1243
- - Backup credentials in code
1244
- - No backup verification/testing
1245
-
1246
- **ORM SPECIFIC:**
1247
- ```javascript
1248
- // Prisma - raw queries
1249
- prisma.$queryRaw`SELECT * FROM users WHERE id = ${userId}` // SAFE
1250
- prisma.$queryRawUnsafe(`SELECT * FROM users WHERE id = ${userId}`) // VULNERABLE
1251
-
1252
- // Sequelize - raw queries
1253
- sequelize.query(`SELECT * FROM ${table}`) // VULNERABLE if table is user input
1254
-
1255
- // TypeORM - raw queries
1256
- repository.query(`SELECT * FROM users WHERE name = '${name}'`) // VULNERABLE
1257
-
1258
- // Mongoose - operator injection
1259
- User.find({ username: req.body.username }) // VULNERABLE to {$gt: ""}
1260
- ```
1261
-
1262
- **AUDIT & LOGGING:**
1263
- - No audit logging for sensitive operations
1264
- - Query logging including sensitive data
1265
- - No tracking of who accessed what data
1266
- - Missing created_at/updated_at timestamps
1267
- - No soft delete (audit trail lost)
1268
-
1269
- Example finding:
1270
- ```json
1271
- {
1272
- "id": "DB-001",
1273
- "title": "SQL injection via string concatenation",
1274
- "severity": "critical",
1275
- "fixOwner": "developer",
1276
- "fixType": "code",
1277
- "file": "src/repositories/user.ts",
1278
- "line": 34,
1279
- "code": "db.query(`SELECT * FROM users WHERE id = ${userId}`)",
1280
- "description": "User ID is concatenated directly into SQL query, allowing SQL injection attacks.",
1281
- "recommendation": "Use parameterized query: db.query('SELECT * FROM users WHERE id = $1', [userId])"
1282
- }
1283
- ```
1284
-
1285
- For EACH finding, output the FULL JSON format.
1286
-
1287
- ---
1288
-
1289
- ### AGENT 16: Network & Architecture Scanner (ID prefix: ARCH)
1290
-
1291
- Scan {{PROJECT_PATH}} for network architecture and service boundary issues.
1292
-
1293
- **CRITICAL DISTINCTION - Code vs Infrastructure fixes:**
1294
-
1295
- For EACH finding, determine:
1296
- - Is this fixable by changing CODE? → fixOwner: "developer"
1297
- - Is this fixable by NetworkPolicy/firewall/K8s config? → fixOwner: "devops"
1298
- - Does this need architecture redesign? → fixOwner: "architect"
1299
-
1300
- CHECK FOR:
1301
-
1302
- **SERVICE BOUNDARIES:**
1303
- - Internal endpoints exposed externally (should be internal-only)
1304
- - Missing network segmentation between services
1305
- - Service-to-service communication without mTLS
1306
- - Internal IPs hardcoded instead of service discovery
1307
- - Admin/debug ports accessible from outside
1308
-
1309
- **TRUST BOUNDARIES:**
1310
- - Which endpoints are meant to be internal-only?
1311
- - Are internal endpoints protected by network policy OR code auth?
1312
- - Document the INTENDED architecture, not just what's missing
1313
-
1314
- **KUBERNETES/INFRASTRUCTURE:**
1315
- - Missing NetworkPolicies for namespace isolation
1316
- - Services using ClusterIP that should be internal
1317
- - LoadBalancer exposing internal services
1318
- - Missing Ingress rules for path-based routing
1319
- - Pod-to-pod communication without restrictions
1320
-
1321
- **FOR EACH FINDING, specify:**
1322
- ```json
1323
- {
1324
- "fixOwner": "devops",
1325
- "fixType": "infrastructure",
1326
- "recommendation": "Add NetworkPolicy to restrict /api/v1/internal/* to enclave namespace only",
1327
- "notCodeFix": true
1328
- }
1329
- ```
1330
-
1331
- If you find an endpoint that lacks authentication but is INTENDED to be protected by network policy:
1332
- - Mark as fixOwner: "devops", NOT "developer"
1333
- - Recommendation should be NetworkPolicy, NOT code auth
1334
- - Add note: "Protected by network segmentation - verify NetworkPolicy exists"
1335
-
1336
- For EACH finding, output the FULL JSON format.
1337
-
1338
- ---
1339
-
1340
- ### AGENT 17: Design Decision Detector (ID prefix: DESIGN)
1341
-
1342
- Scan {{PROJECT_PATH}} for intentional design decisions that might look like bugs.
1343
-
1344
- **GOAL: Prevent false positives by identifying documented/intentional patterns**
1345
-
1346
- CHECK FOR:
1347
-
1348
- **DOCUMENTED DECISIONS:**
1349
- - Comments explaining WHY something is done a certain way
1350
- - README/docs explaining architecture choices
1351
- - ADR (Architecture Decision Records) files
1352
- - SECURITY.md or similar documentation
1353
-
1354
- **INTENTIONAL PATTERNS:**
1355
- - Content filtering disabled with comment "for transparency"
1356
- - Auth bypassed for specific endpoints with documentation
1357
- - Longer session timeouts with business justification
1358
- - Relaxed validation with explicit reason
1359
-
1360
- **CODE PATTERNS THAT ARE NOT BUGS:**
1361
- - `// Intentional: ....` or `// Design decision: ...`
1362
- - `// SECURITY: This is safe because...`
1363
- - `// TODO: This is acceptable for now because...`
1364
- - Feature flags controlling security features with documentation
1365
-
1366
- **FOR EACH PATTERN FOUND, output:**
1367
- ```json
1368
- {
1369
- "id": "DESIGN-001",
1370
- "type": "documented_decision",
1371
- "title": "Content filtering disabled",
1372
- "file": "src/ai/chat.ts",
1373
- "line": 45,
1374
- "reason": "Documented in code comment: 'Disabled for transparency, users see raw AI output'",
1375
- "relatedFindings": ["AI-001"],
1376
- "recommendation": "Not a bug - document in security overview as accepted risk"
1377
- }
1378
- ```
1379
-
1380
- These findings will be EXCLUDED from the main report and moved to "Design Decisions" section.
1381
-
1382
- ---
1383
-
1384
- ### AGENT 18: Context-Aware Validator (ID prefix: CTX)
1385
-
1386
- Scan {{PROJECT_PATH}} to understand the CONTEXT of each potential finding.
1387
-
1388
- **GOAL: Reduce false positives by understanding deployment context**
1389
-
1390
- FOR EACH FINDING FROM OTHER AGENTS, determine:
1391
-
1392
- **DEPLOYMENT CONTEXT:**
1393
- - Is this code running in a container with network isolation?
1394
- - Is this behind an API gateway that handles auth?
1395
- - Is this internal-only service behind VPN?
1396
- - Is there a WAF/CDN in front that mitigates this?
1397
-
1398
- **RUNTIME CONTEXT:**
1399
- - Is this code path actually reachable in production?
1400
- - Is this only used in development/testing?
1401
- - Is this dead code or deprecated?
1402
- - Is this protected by feature flag that's disabled?
1403
-
1404
- **DATA FLOW CONTEXT:**
1405
- - Is the input already validated upstream?
1406
- - Is the output sanitized downstream?
1407
- - Is there middleware that applies to this route?
1408
-
1409
- **OUTPUT:**
1410
- ```json
1411
- {
1412
- "findingId": "SEC-001",
1413
- "contextAnalysis": {
1414
- "deploymentContext": "Runs in K8s with NetworkPolicy restricting access",
1415
- "runtimeContext": "Only reachable from internal services",
1416
- "dataFlowContext": "Input validated by Zod at API gateway level",
1417
- "verdict": "false_positive|confirmed|needs_review",
1418
- "reason": "Protected by network policy - not externally accessible"
1419
- }
1420
- }
1421
- ```
1422
-
1423
- ---
1424
-
1425
- ### AGENT 19: Enclave & Trusted Compute Scanner (ID prefix: ENC)
1426
-
1427
- **CONDITIONAL AGENT** - First detect if this project uses enclaves/TEE:
1428
-
1429
- ```bash
1430
- # Search for enclave/TEE indicators
1431
- grep -r -l "enclave\|nitro\|sgx\|tee\|attestation\|trusted.compute\|confidential.computing\|vsock" --include="*.ts" --include="*.js" --include="*.py" --include="*.yaml" --include="*.yml" .
1432
- ```
1433
-
1434
- **IF NO ENCLAVE CODE FOUND**: Output and skip:
1435
- ```json
1436
- {"skipped": true, "reason": "No enclave/TEE code detected in project", "findings": []}
1437
- ```
1438
-
1439
- **IF ENCLAVE CODE FOUND**: Scan {{PROJECT_PATH}} for enclave/TEE/trusted compute specific patterns.
1440
-
1441
- CHECK FOR:
1442
-
1443
- **ENCLAVE REGISTRATION:**
1444
- - Enclave-to-backend registration without attestation
1445
- - IP-based trust without cryptographic verification
1446
- - Missing remote attestation flow
1447
- - Enclave secrets transmitted without encryption
1448
-
1449
- **TRUST MODEL:**
1450
- - What is the trust boundary between enclave and host?
1451
- - Is the communication channel authenticated?
1452
- - Are enclave outputs verified?
1453
-
1454
- **SPECIFIC PATTERNS:**
1455
- - /register endpoints for enclave → backend (common pattern)
1456
- - Heartbeat/health endpoints from enclave
1457
- - Configuration push to enclave
1458
-
1459
- **FOR ENCLAVE ENDPOINTS, determine:**
1460
- - Is this MEANT to be protected by network only? → Note in finding
1461
- - Is attestation planned but not implemented? → Check TODOs/roadmap
1462
- - Is this MVP/temporary solution? → Check for documentation
1463
-
1464
- Output findings with proper fixOwner:
1465
- - Network protection needed → fixOwner: "devops"
1466
- - Attestation needed → fixOwner: "architect" (design change)
1467
- - Code validation needed → fixOwner: "developer"
1468
-
1469
- ---
1470
-
1471
- ### AGENT 20: Executive Summary Generator (ID prefix: EXEC)
1472
-
1473
- After all other agents complete, generate an executive summary **written for leadership** — technically precise but accessible.
1474
-
1475
- **WRITING GUIDELINES:**
1476
- - The `overview` field should read like a professional security consultant's opening paragraph
1477
- - Start with 1 sentence describing what the project IS (architecture, purpose)
1478
- - Then state the overall security posture clearly
1479
- - Then list the most significant remaining issues in one sentence
1480
- - Use specific numbers and technical details, not vague language
1481
-
1482
- **EXAMPLE of professional executive summary overview:**
1483
- "Express-AI Officely is a confidential AI platform built on a three-tier encrypted architecture: a Next.js frontend with BFF pattern, an Express.js API gateway on EKS, and backend enclaves running inside AMD SEV-SNP encrypted VMs. No critical vulnerabilities remain. The most significant remaining issues are: unauthenticated enclave registration endpoints that could allow enclave impersonation (mitigated by network-level whitelisting), hardcoded secrets in Helm values, a monolithic 1000+ line chat handler creating maintenance risk, 3,200 lines of dead or duplicated code (5.3% of the codebase), and zero test coverage across all components."
1484
-
1485
- **TOP RISKS writing quality:**
1486
- Each risk must be a specific, actionable description — not a generic category.
1487
- - BAD: "SQL injection vulnerability"
1488
- - GOOD: "Unauthenticated enclave registration endpoints could allow impersonation (mitigated by network whitelisting)"
1489
- - GOOD: "160 lines of Redis metrics tracking duplicated verbatim between streaming/non-streaming paths"
1490
-
1491
- **OUTPUT FORMAT:**
1492
- ```json
1493
- {
1494
- "executiveSummary": {
1495
- "headline": "0 Critical + 7 High findings — platform hardened but key gaps remain",
1496
- "riskLevel": "HIGH",
1497
- "overview": "Professional 2-3 sentence summary as described above.",
1498
- "topRisks": [
1499
- "Specific risk description with technical detail and context",
1500
- "Another risk with file reference and impact quantification",
1501
- "Third risk with mitigation status noted if partial"
1502
- ],
1503
- "positives": [
1504
- "Specific strength with technical evidence — not generic praise",
1505
- "Another strength citing specific libraries/patterns/algorithms"
1506
- ],
1507
- "recommendedActions": [
1508
- {
1509
- "priority": 1,
1510
- "action": "Remove hardcoded secrets from Helm values. Move to Secrets Manager. Rotate keys immediately.",
1511
- "owner": "devops",
1512
- "effort": "2-4 hours"
1513
- },
1514
- {
1515
- "priority": 2,
1516
- "action": "Add shared-secret or mTLS auth to enclave status/register endpoints",
1517
- "owner": "architect",
1518
- "effort": "1-2 days"
1519
- }
1520
- ],
1521
- "byOwner": {
1522
- "developer": 5,
1523
- "devops": 3,
1524
- "architect": 1
1525
- },
1526
- "priorityRoadmap": {
1527
- "P0_immediate": {
1528
- "description": "Fix this sprint - security critical",
1529
- "findings": ["SEC-001", "AUTH-003"],
1530
- "effort": "1-2 days"
1531
- },
1532
- "P1_short_term": {
1533
- "description": "Fix within 2 weeks - high priority",
1534
- "findings": ["API-002", "INFRA-005"],
1535
- "effort": "3-5 days"
1536
- },
1537
- "P2_medium_term": {
1538
- "description": "Fix within month - important",
1539
- "findings": ["QUAL-001", "DEAD-003"],
1540
- "effort": "1 week"
1541
- },
1542
- "P3_backlog": {
1543
- "description": "Address when capacity allows",
1544
- "findings": ["TEST-001"],
1545
- "effort": "ongoing"
1546
- }
1547
- }
1548
- }
1549
- }
1550
- ```
1551
-
1552
- **Priority Assignment Rules:**
1553
- - **P0 (Immediate)**: CRITICAL severity, actively exploitable, data breach risk
1554
- - **P1 (Short-term)**: HIGH severity, requires auth to exploit, compliance risk
1555
- - **P2 (Medium-term)**: MEDIUM severity, defense-in-depth, code quality
1556
- - **P3 (Backlog)**: LOW/INFO severity, nice-to-have improvements
1557
-
1558
- ---
1559
-
1560
- ### AGENT 22: Runtime Verification Scanner (ID prefix: RUNTIME)
1561
-
1562
- **CONDITIONAL AGENT** - Only runs if SSH is configured in Phase 0.
1563
-
1564
- Check if runtime.json was found in Phase 0:
1565
- - If NO runtime.json → Skip this agent entirely
1566
- - If runtime.json exists → Proceed with runtime verification
1567
-
1568
- **PURPOSE**: Find dangerous mismatches between code configuration and actual runtime environment.
1569
-
1570
- **Example of what this catches:**
1571
- > The code says `USER appuser` in Dockerfile, but the container actually runs as `root`.
1572
- > This is why a DuckDB file read vulnerability could access /etc/passwd!
1573
-
1574
- ---
1575
-
1576
- **STEP 1: Gather Code Expectations**
1577
-
1578
- Analyze configuration files to understand EXPECTED runtime state:
11
+ ### Step 1: Understand the Project
1579
12
 
1580
13
  ```bash
1581
- # Dockerfile
1582
- grep -E "^USER|^EXPOSE|^ENV" Dockerfile 2>/dev/null
1583
-
1584
- # Docker Compose
1585
- grep -E "user:|ports:|environment:" docker-compose*.yml 2>/dev/null
1586
-
1587
- # Kubernetes
1588
- grep -E "runAsUser|runAsNonRoot|readOnlyRootFilesystem|securityContext" k8s/*.yaml helm/**/values.yaml 2>/dev/null
14
+ mkdir -p .coverme
1589
15
 
1590
- # PM2
1591
- grep -E "user|uid|cwd" ecosystem.config.js pm2.config.js 2>/dev/null
16
+ # Project structure
17
+ ls -la
18
+ find . -maxdepth 2 -type d -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" 2>/dev/null | head -40
1592
19
 
1593
- # Systemd
1594
- grep -E "^User=|^Group=" *.service 2>/dev/null
1595
- ```
20
+ # Count files
21
+ 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
1596
22
 
1597
- Build expected state:
1598
- ```json
1599
- {
1600
- "expected": {
1601
- "user": "appuser",
1602
- "uid": 1000,
1603
- "runAsRoot": false,
1604
- "readOnlyFs": true,
1605
- "ports": [3000],
1606
- "source": "Dockerfile:15 - USER appuser"
1607
- }
1608
- }
23
+ # Tech stack
24
+ cat package.json 2>/dev/null | head -40
1609
25
  ```
1610
26
 
1611
- ---
1612
-
1613
- **STEP 2: SSH and Check Actual Runtime**
1614
-
1615
- Use the SSH configuration from runtime.json:
27
+ ### Step 2: Find Critical Files
1616
28
 
1617
29
  ```bash
1618
- # Build SSH command (from runtime.json)
1619
- # host: user@server.com, port: 22, keyPath: ~/.ssh/id_rsa
1620
-
1621
- # Check who is running the process
1622
- ssh user@server.com "ps -eo user,pid,cmd | grep -E 'node|python|java|pm2' | head -5"
1623
-
1624
- # Check Docker container user
1625
- ssh user@server.com "docker ps -q | head -1 | xargs -I {} docker exec {} id"
1626
-
1627
- # Check Kubernetes pod user
1628
- ssh user@server.com "kubectl get pods -o name | head -1 | xargs -I {} kubectl exec {} -- id"
1629
-
1630
- # Check file permissions
1631
- ssh user@server.com "ls -la /app/ 2>/dev/null | head -10"
1632
-
1633
- # Check listening ports
1634
- ssh user@server.com "ss -tlnp | grep -E ':3000|:8080|:6379'"
1635
- ```
1636
-
1637
- Build actual state:
1638
- ```json
1639
- {
1640
- "actual": {
1641
- "user": "root",
1642
- "uid": 0,
1643
- "runAsRoot": true,
1644
- "readOnlyFs": false,
1645
- "ports": [3000, 6379],
1646
- "evidence": "uid=0(root) gid=0(root)"
1647
- }
1648
- }
1649
- ```
1650
-
1651
- ---
1652
-
1653
- **STEP 3: Compare and Generate Findings**
1654
-
1655
- | Mismatch | Severity | ID |
1656
- |----------|----------|-----|
1657
- | Code says non-root, runs as root | CRITICAL | RUNTIME-001 |
1658
- | Dockerfile USER ignored | CRITICAL | RUNTIME-002 |
1659
- | K8s runAsNonRoot:true but runs as root | HIGH | RUNTIME-003 |
1660
- | ReadOnlyRootFilesystem not enforced | HIGH | RUNTIME-004 |
1661
- | Unexpected ports exposed | MEDIUM | RUNTIME-005 |
1662
- | File permissions too open (777) | MEDIUM | RUNTIME-006 |
1663
- | Environment variables mismatch | LOW | RUNTIME-007 |
1664
-
1665
- **Output Format:**
1666
- ```json
1667
- {
1668
- "id": "RUNTIME-001",
1669
- "title": "Container running as root despite USER directive",
1670
- "severity": "critical",
1671
- "category": "runtime-mismatch",
1672
- "fixOwner": "devops",
1673
- "fixType": "infrastructure",
1674
-
1675
- "expected": {
1676
- "value": "appuser (uid 1000)",
1677
- "source": "Dockerfile:15",
1678
- "code": "USER appuser"
1679
- },
1680
-
1681
- "actual": {
1682
- "value": "root (uid 0)",
1683
- "command": "docker exec container id",
1684
- "evidence": "uid=0(root) gid=0(root)"
1685
- },
1686
-
1687
- "description": "The Dockerfile specifies USER appuser, but the container runs as root. This likely means docker-compose or K8s overrides the user.",
1688
-
1689
- "impact": "Running as root means any code vulnerability can access ALL system files. The DuckDB read_text() issue could read /etc/shadow, SSH keys, or any file on the system.",
1690
-
1691
- "recommendation": "1. Remove user: root from docker-compose.yml\n2. Add securityContext.runAsNonRoot: true to K8s deployment\n3. Verify no --user root in docker run commands",
1692
-
1693
- "verification": {
1694
- "codeFile": "Dockerfile:15",
1695
- "sshCommand": "docker exec container_name id",
1696
- "sshOutput": "uid=0(root) gid=0(root)"
1697
- }
1698
- }
1699
- ```
1700
-
1701
- ---
1702
-
1703
- ## PHASE 2: DUPLICATE & EXISTING SOLUTIONS CHECK
1704
-
1705
- ### AGENT 21: Duplicate & Existing Solutions Scanner (ID prefix: DUP)
1706
-
1707
- CRITICAL: Before recommending ANY fix, check if a solution ALREADY EXISTS in the codebase.
1708
-
1709
- For EVERY finding from Phase 1, search the codebase for:
1710
-
1711
- 1. **Existing utilities/helpers that solve this**:
1712
- - Search for similar function names (sanitize, validate, escape, hash, encrypt)
1713
- - Check utils/, helpers/, lib/, common/ folders
1714
- - Look for imported libraries that handle this
1715
-
1716
- 2. **Existing patterns in the codebase**:
1717
- - How do OTHER files handle the same issue?
1718
- - Is there a project-wide convention?
1719
- - Are there shared middleware/decorators?
30
+ # Auth files
31
+ find . -type f \( -name "*auth*" -o -name "*session*" -o -name "*jwt*" -o -name "*login*" \) -not -path "*/node_modules/*" 2>/dev/null | head -15
1720
32
 
1721
- 3. **Configuration that already exists**:
1722
- - Check if there's a config for this (CSP headers, CORS, rate limits)
1723
- - Look in config/, .env files, infrastructure code
33
+ # API routes
34
+ find . -type f \( -name "*route*" -o -name "*controller*" -o -name "*api*" -o -name "*endpoint*" \) -not -path "*/node_modules/*" 2>/dev/null | head -15
1724
35
 
1725
- 4. **Duplicate findings & Cross-References**:
1726
- - Is this the same issue reported multiple times?
1727
- - Are multiple findings actually ONE root cause?
1728
- - **Create CR-xx IDs** when same issue found by multiple agents
36
+ # Security middleware
37
+ find . -type f \( -name "*middleware*" -o -name "*guard*" -o -name "*interceptor*" \) -not -path "*/node_modules/*" 2>/dev/null | head -10
1729
38
 
1730
- **Cross-Reference (CR-xx) Rules:**
1731
- When two or more agents find the SAME underlying issue from different perspectives:
1732
- 1. Create a cross-reference ID: `CR-01`, `CR-02`, etc.
1733
- 2. Merge into single finding with dual ID: `"CR-02 / T-EKS-3"`
1734
- 3. Use the most descriptive title
1735
- 4. Combine descriptions from both perspectives
1736
- 5. Use the higher DREAD score
1737
- 6. Add both original IDs to `crossReferences` array
39
+ # Config and secrets
40
+ find . -type f \( -name "*.env*" -o -name "*secret*" -o -name "*config*" -o -name "*credential*" \) -not -path "*/node_modules/*" 2>/dev/null | head -15
1738
41
 
1739
- **Examples of cross-references:**
1740
- - SEC finds "hardcoded API key" + INFRA finds same key in Helm `CR-01 / SEC-005 / INFRA-003`
1741
- - AUTH finds "missing MFA" + BIZ finds "MFA bypass flow" → Keep separate but add crossReferences
1742
- - QUAL finds "DRY violation" + PERF finds same duplicated code → Merge as `CR-02`
1743
-
1744
- For EACH finding, add to the checkBefore field:
1745
- - "EXISTING: Found sanitizeHtml() in src/utils/security.ts - use this instead of creating new"
1746
- - "PATTERN: Other files use zod.string().email() for validation - follow same pattern"
1747
- - "DUPLICATE: This is same root cause as SEC-003, fix once in middleware"
1748
- - "CONFIG: Rate limiting already configured in src/middleware/rateLimit.ts line 15"
1749
-
1750
- If NO existing solution found, state: "VERIFIED: No existing solution found, new implementation needed"
1751
-
1752
- Output for each finding:
1753
- ```json
1754
- {
1755
- "findingId": "SEC-001",
1756
- "existingSolution": "Found: src/utils/sanitize.ts exports sanitizeUserInput()",
1757
- "duplicateOf": null,
1758
- "crossReferenceId": null,
1759
- "relatedFindings": ["INFRA-003"],
1760
- "suggestedApproach": "Import and use existing sanitizeUserInput() instead of creating new function",
1761
- "checkBefore": "1. Verify sanitizeUserInput() handles this case 2. Check if it's already imported"
1762
- }
1763
- ```
1764
-
1765
- **Cross-Reference output when merging:**
1766
- ```json
1767
- {
1768
- "crossReference": {
1769
- "id": "CR-02",
1770
- "mergedFindings": ["SEC-005", "INFRA-003"],
1771
- "title": "Hardcoded Tracker API Keys in Helm Values and Backend Code",
1772
- "reason": "Same hardcoded key found in both application code and infrastructure config"
1773
- }
1774
- }
1775
- ```
1776
-
1777
- ---
1778
-
1779
- ## PHASE 3: MITIGATION VALIDATION (CRITICAL)
1780
-
1781
- **This phase determines if findings are ACTUALLY exploitable or if other code prevents the attack.**
1782
-
1783
- ### Validator M: Mitigation Hunter
1784
-
1785
- For EVERY finding from Phase 1+2, actively search the codebase for mitigations:
1786
-
1787
- #### Search Checklist:
1788
- 1. **Input Validation** - Is input sanitized before reaching the vulnerable sink?
1789
- ```bash
1790
- grep -r "validate|sanitize|escape|Zod|Joi|yup" src/
1791
- ```
1792
-
1793
- 2. **Middleware Protection** - Is there middleware that protects this route?
1794
- ```bash
1795
- grep -r "app.use|helmet|csrf|rateLimit" src/
1796
- ```
1797
-
1798
- 3. **Framework Auto-Protection** - Does the framework handle this automatically?
1799
- - React JSX auto-escapes (unless dangerouslySetInnerHTML)
1800
- - Prisma/TypeORM parameterize queries automatically
1801
- - Next.js API routes have built-in protections
1802
-
1803
- 4. **Route Protection** - Is the endpoint protected by auth/authorization?
1804
- ```bash
1805
- grep -r "requireAuth|isAdmin|authorize" src/
1806
- ```
1807
-
1808
- 5. **Configuration** - Is there security config that applies?
1809
- - CSP headers blocking XSS
1810
- - CORS restricting origins
1811
- - Rate limiting preventing abuse
1812
-
1813
- #### Output Per Finding:
1814
- ```json
1815
- {
1816
- "findingId": "SEC-001",
1817
- "verdict": "mitigated|partial|confirmed|false_positive",
1818
- "mitigationType": "input_validation|middleware|framework|config|none",
1819
- "evidence": [
1820
- "Found Zod validation at src/routes/user.ts:23",
1821
- "Schema restricts input to alphanumeric only",
1822
- "XSS payload would fail validation"
1823
- ],
1824
- "adjustedSeverity": "low",
1825
- "codeReferences": [
1826
- {"file": "src/middleware/validate.ts", "line": 45}
1827
- ]
1828
- }
1829
- ```
1830
-
1831
- **Verdicts:**
1832
- - `mitigated` - Another control fully prevents the attack → Remove from report or mark as INFO
1833
- - `partial` - Some protection but can be bypassed → Keep but may downgrade severity
1834
- - `confirmed` - No mitigation found → Keep original severity
1835
- - `false_positive` - Finding is incorrect (test file, dead code, etc.) → Remove
1836
-
1837
- ---
1838
-
1839
- ## PHASE 4: CROSS-VALIDATION
1840
-
1841
- Launch 3 validators IN PARALLEL after Phase 3 completes:
1842
-
1843
- ### Validator A: False Positive & Duplicate Hunter
1844
-
1845
- Review ALL findings that passed Phase 3 (not mitigated).
1846
- For each finding determine if it's FALSE POSITIVE or DUPLICATE:
1847
- - Is the code actually reachable?
1848
- - Is the context misunderstood?
1849
- - Is this a DUPLICATE of another finding? (same root cause)
1850
- - Does an EXISTING SOLUTION already exist in the codebase?
1851
-
1852
- If existing solution found, mark as "use_existing" not "fix_new".
1853
-
1854
- Output:
1855
- ```json
1856
- {
1857
- "confirmed": ["SEC-001", "AUTH-002"],
1858
- "useExisting": [
1859
- {"id": "SEC-005", "existingSolution": "src/utils/sanitize.ts", "reason": "sanitizeHtml() already exists"}
1860
- ],
1861
- "duplicates": [
1862
- {"id": "SEC-007", "duplicateOf": "SEC-003", "reason": "Same XSS issue, fix once in shared component"}
1863
- ],
1864
- "falsePositives": [
1865
- {"id": "API-003", "reason": "Input is validated by Zod schema at line 45"}
1866
- ]
1867
- }
42
+ # Infrastructure
43
+ find . -type f \( -name "Dockerfile*" -o -name "docker-compose*" -o -name "*.yaml" -o -name "*.yml" \) -not -path "*/node_modules/*" 2>/dev/null | head -20
1868
44
  ```
1869
45
 
1870
- ### Validator B: Evidence Challenger
1871
-
1872
- For every HIGH and CRITICAL finding:
1873
- - Read the actual code files
1874
- - Trace complete data flow
1875
- - Verify exploit scenario is realistic
1876
- - Check if exploitable in production context
1877
-
1878
- Output same format as Validator A.
1879
-
1880
- ### Validator C: Missing Issues Hunter
1881
-
1882
- Look for issues Phase 1 agents MISSED:
1883
- - Edge cases
1884
- - Combination attacks
1885
- - Business logic flaws specific to this codebase
1886
- - Configuration issues
1887
- - Integration points
46
+ ### Step 3: Check Previous Scan
1888
47
 
1889
- Output:
1890
- ```json
1891
- {
1892
- "missedIssues": [{"full finding object"}]
1893
- }
48
+ ```bash
49
+ cat .coverme/scan.json 2>/dev/null | head -50 || echo "NO_PREVIOUS_SCAN"
1894
50
  ```
1895
51
 
1896
52
  ---
1897
53
 
1898
- ## PHASE 5: CROSS-REFERENCE MERGE
1899
-
1900
- Before generating final output, identify findings that describe the same issue from different agent perspectives.
1901
-
1902
- **Merge Process:**
1903
- 1. Compare all findings from Phase 1-4
1904
- 2. If two findings reference the same file+line range OR describe the same root cause:
1905
- - Create a SINGLE finding with dual ID: "CR-02 / T-EKS-3"
1906
- - Use the most descriptive title from either finding
1907
- - Combine description details from both perspectives
1908
- - Use the higher DREAD score
1909
- - Populate `crossReferences` with both original IDs
1910
- 3. If findings are RELATED but NOT identical:
1911
- - Keep as separate findings
1912
- - Add each other's ID to `crossReferences` array
1913
-
1914
- **Examples of cross-referenced findings:**
1915
- - Security agent finds hardcoded key + Infrastructure agent finds same key in Helm values → MERGE
1916
- - Auth agent finds missing MFA + Business logic agent finds MFA bypass → ADD crossReferences
1917
- - Quality agent finds DRY violation in metrics code + Security agent finds same code → MERGE
1918
-
1919
- ---
54
+ ## PHASE 2: DEEP ANALYSIS
1920
55
 
1921
- ## PHASE 6: POSITIVE OBSERVATIONS
56
+ **Read the critical files you found.** For each file, look for:
1922
57
 
1923
- Scan for good practices to include in the report. Each positive observation must include **specific technical evidence** — not generic praise.
58
+ ### Security (SEC)
59
+ - SQL/NoSQL Injection - string concatenation in queries
60
+ - XSS - unsanitized output
61
+ - Command Injection - user input in shell commands
62
+ - Path Traversal - user input in file paths
63
+ - SSRF - user-controlled URLs
64
+ - Hardcoded Secrets - API keys, passwords in code
65
+ - Weak Crypto - MD5, SHA1 for passwords, weak random
1924
66
 
1925
- **FORMAT for each observation:**
1926
- ```json
1927
- {
1928
- "title": "Descriptive Title — 3-5 words",
1929
- "description": "2-3 sentences of specific technical evidence. Name the specific functions, libraries, patterns, or configurations that demonstrate this strength. Include file references where relevant."
1930
- }
1931
- ```
67
+ ### Authentication (AUTH)
68
+ - JWT issues - algorithm confusion, missing validation
69
+ - Session fixation
70
+ - Password storage - plaintext, weak hashing
71
+ - Missing MFA
72
+ - OAuth misconfigurations
1932
73
 
1933
- **BAD (generic, no evidence):**
1934
- - "Good authentication implementation"
1935
- - "Proper input validation"
1936
- - "Secure coding practices"
74
+ ### API Security (API)
75
+ - Missing input validation
76
+ - No rate limiting
77
+ - CORS misconfigurations
78
+ - Missing authentication on endpoints
79
+ - Mass assignment
1937
80
 
1938
- **GOOD (specific, with evidence):**
1939
- - {"title": "Zero-Knowledge Architecture", "description": "EKS gateway genuinely never sees plaintext. Encrypted payloads flow through without decryption. Well-enforced across all components."}
1940
- - {"title": "Atomic Credit Operations", "description": "Lua scripts for token burning and balance deduction prevent cross-pod race conditions. Check-and-deduct is atomic."}
1941
- - {"title": "Post-Quantum Cryptography", "description": "XWing (ML-KEM-768 + X25519) hybrid KEM, Ed25519 signing, AES-256-GCM. Key derivation: Argon2id + HKDF with proper alignment across browser/Node.js."}
1942
- - {"title": "Secure File Handling", "description": "MIME + magic number validation, memory-only storage, size limits. secureDeleteFile() overwrites with random data before deletion."}
81
+ ### Infrastructure (INFRA)
82
+ - Docker running as root
83
+ - Secrets in docker-compose
84
+ - Missing securityContext in K8s
85
+ - No NetworkPolicy
86
+ - Secrets in git history
87
+ - CI/CD security issues
1943
88
 
1944
- **CHECK FOR:**
1945
- - Security controls that work well (name the specific middleware, library, or pattern)
1946
- - Authentication/authorization strengths (name the provider, flow, and protections)
1947
- - Input validation patterns (name the library and coverage)
1948
- - Cryptographic implementations (name algorithms, key sizes, modes)
1949
- - Architecture strengths (name the pattern and why it's secure)
1950
- - Operational security (logging, monitoring, incident response)
89
+ ### Business Logic (BIZ)
90
+ - Race conditions (TOCTOU)
91
+ - Authorization bypass
92
+ - Quota/credit manipulation
93
+ - Workflow bypass
1951
94
 
1952
- Output as array of objects with `title` and `description` fields.
95
+ ### Code Quality (QUAL)
96
+ - No tests for security code
97
+ - Dead code
98
+ - Missing error handling
1953
99
 
1954
100
  ---
1955
101
 
1956
- ## PHASE 7: BUILD CONSENSUS & GENERATE OUTPUT
1957
-
1958
- ### CRITICAL: Actually Remove False Positives!
1959
-
1960
- The final report should ONLY contain findings that are:
1961
- 1. **Confirmed** by mitigation validation (no existing protection found)
1962
- 2. **Partial** mitigations (some protection but incomplete)
102
+ ## PHASE 3: GENERATE REPORT
1963
103
 
1964
- **DO NOT INCLUDE** findings that are:
1965
- - `mitigated` - full protection exists elsewhere
1966
- - `false_positive` - not actually a vulnerability
1967
- - Intentional design decisions with documented comments
1968
- - Race conditions protected by atomic operations (Lua, transactions)
1969
-
1970
- ### Step-by-Step Process:
1971
-
1972
- 1. **Start with all Phase 1 findings**
1973
-
1974
- 2. **Apply Mitigation Validator results (Phase 3):**
1975
- - `mitigated` → REMOVE from findings, add to `mitigatedFindings` array
1976
- - `false_positive` → REMOVE from findings, add to `falsePositives` array
1977
- - `partial` → KEEP but downgrade severity if specified
1978
- - `confirmed` → KEEP with original severity
1979
-
1980
- 3. **Apply Cross-Validator results (Phase 4):**
1981
- - Additional false positives → REMOVE from findings
1982
- - Duplicates → Merge into single finding
1983
-
1984
- 4. **Calculate final counts AFTER removals:**
1985
- - Only count findings that remain in the `findings` array
1986
- - Do NOT count mitigated or false positive findings
1987
-
1988
- 5. **Add missed issues from Validator C**
1989
-
1990
- 6. **Sort remaining findings:** severity DESC, confidence DESC
1991
-
1992
- ### Final JSON Structure
104
+ Create `.coverme/scan.json` with this structure:
1993
105
 
1994
106
  ```json
1995
107
  {
1996
108
  "projectName": "project-name",
1997
- "scanDate": "{{SCAN_DATE}}",
1998
- "filesScanned": 45,
1999
- "linesOfCode": 4850,
2000
- "projectTree": "project-name/\n├── src/\n│ ├── api/\n│ ├── services/\n│ └── utils/\n├── tests/\n└── package.json",
2001
-
109
+ "scanDate": "2026-02-18T12:00:00Z",
110
+ "filesScanned": 100,
111
+ "linesOfCode": 15000,
112
+ "projectTree": "project/\n├── src/\n│ ├── routes/\n│ ├── services/\n│ └── middleware/\n├── tests/\n└── package.json",
2002
113
  "projectOverview": {
2003
- "name": "project-name",
2004
- "type": "Backend API | Full-stack | etc",
2005
- "stack": ["Node.js", "TypeScript", "React", "PostgreSQL"],
2006
- "purpose": "Brief description of what this project does",
114
+ "name": "Project Name",
115
+ "type": "Backend API",
116
+ "stack": ["Node.js", "TypeScript", "PostgreSQL"],
117
+ "purpose": "What this project does in 1-2 sentences",
2007
118
  "architecture": "Monolith | Microservices | Serverless",
2008
- "keyComponents": ["auth service", "payment processing", "AI chat"]
119
+ "keyComponents": ["src/routes/", "src/services/"]
2009
120
  },
2010
-
2011
121
  "executiveSummary": {
2012
- "headline": "3 Critical + 5 High findings require immediate attention",
122
+ "headline": "X Critical + Y High findings - brief assessment",
2013
123
  "riskLevel": "CRITICAL | HIGH | MEDIUM | LOW",
2014
- "overview": "A 2-3 sentence executive summary of the project architecture AND the overall security posture, written for leadership. Example: 'Express-AI Officely is a confidential AI platform built on a three-tier encrypted architecture. No critical vulnerabilities remain. The most significant remaining issues are: unauthenticated registration endpoints, hardcoded secrets in Helm values, and zero test coverage.'",
124
+ "overview": "2-3 sentence professional summary. Describe the architecture, then the security posture, then the main concerns.",
2015
125
  "topRisks": [
2016
- "Unauthenticated enclave registration endpoints could allow impersonation (mitigated by network whitelisting)",
2017
- "Hardcoded API keys and hash salts in Helm values committed to version control",
2018
- "160 lines of Redis metrics tracking duplicated verbatim between streaming/non-streaming paths"
126
+ "Specific risk with file:line reference",
127
+ "Another risk with quantified impact"
2019
128
  ],
2020
129
  "positives": [
2021
- "Zero-knowledge architecture gateway never sees plaintext",
2022
- "Atomic credit operations via Lua scripts prevent race conditions",
2023
- "Post-quantum cryptography with XWing hybrid KEM"
130
+ "Good practice with specific evidence",
131
+ "Another strength with file reference"
2024
132
  ],
2025
133
  "recommendedActions": [
2026
134
  {
2027
135
  "priority": 1,
2028
- "action": "Remove hardcoded secrets from Helm values. Move to Secrets Manager. Rotate keys.",
2029
- "owner": "devops",
2030
- "effort": "2-4 hours"
2031
- }
2032
- ],
2033
- "byOwner": {
2034
- "developer": 5,
2035
- "devops": 3,
2036
- "architect": 1
2037
- }
2038
- },
2039
-
2040
- "architectureOverview": {
2041
- "components": [
2042
- {
2043
- "name": "API Server",
2044
- "type": "service",
2045
- "description": "Express.js REST API handling all client requests",
2046
- "trustLevel": "semi-trusted"
2047
- },
2048
- {
2049
- "name": "PostgreSQL",
2050
- "type": "database",
2051
- "description": "Primary data store for user and application data",
2052
- "trustLevel": "trusted"
2053
- },
2054
- {
2055
- "name": "Redis",
2056
- "type": "cache",
2057
- "description": "Session storage and rate limiting",
2058
- "trustLevel": "trusted"
2059
- },
2060
- {
2061
- "name": "External Payment API",
2062
- "type": "external",
2063
- "description": "Third-party payment processor",
2064
- "trustLevel": "untrusted"
2065
- }
2066
- ],
2067
- "trustBoundaries": [
2068
- {
2069
- "name": "Client to API",
2070
- "from": "Browser/Mobile",
2071
- "to": "API Server",
2072
- "protocol": "HTTPS"
2073
- },
2074
- {
2075
- "name": "API to Database",
2076
- "from": "API Server",
2077
- "to": "PostgreSQL",
2078
- "protocol": "TLS"
2079
- }
2080
- ],
2081
- "criticalAssets": [
2082
- {
2083
- "name": "User Credentials",
2084
- "type": "credential",
2085
- "location": "PostgreSQL users table",
2086
- "protection": "bcrypt hashed"
2087
- },
2088
- {
2089
- "name": "API Keys",
2090
- "type": "key",
2091
- "location": "Environment variables",
2092
- "protection": "Encrypted at rest"
2093
- },
2094
- {
2095
- "name": "Session Tokens",
2096
- "type": "token",
2097
- "location": "Redis",
2098
- "protection": "HMAC signed"
136
+ "action": "Specific action to take",
137
+ "owner": "developer",
138
+ "effort": "2-3 days"
2099
139
  }
2100
- ],
2101
- "dataFlows": [
2102
- "User Authentication Flow",
2103
- "Payment Processing Flow",
2104
- "Data Export Flow"
2105
140
  ]
2106
141
  },
2107
-
2108
- "threatModel": [
2109
- {
2110
- "id": "T-001",
2111
- "threat": "SQL Injection via user input",
2112
- "category": "STRIDE",
2113
- "strideType": "T",
2114
- "status": "open",
2115
- "relatedFindings": ["SEC-001", "DB-002"],
2116
- "mitigation": "Use parameterized queries",
2117
- "dreadScore": 8.5
2118
- },
2119
- {
2120
- "id": "T-002",
2121
- "threat": "Session hijacking via XSS",
2122
- "category": "STRIDE",
2123
- "strideType": "S",
2124
- "status": "partial",
2125
- "relatedFindings": ["SEC-003"],
2126
- "mitigation": "CSP headers implemented but not comprehensive",
2127
- "dreadScore": 7.2
2128
- },
2129
- {
2130
- "id": "T-003",
2131
- "threat": "Unauthorized data access",
2132
- "category": "LINDDUN",
2133
- "status": "mitigated",
2134
- "relatedFindings": [],
2135
- "mitigation": "Row-level security implemented",
2136
- "dreadScore": 3.0
2137
- }
2138
- ],
2139
-
2140
- "qualityReview": {
2141
- "deleteItems": [
2142
- {
2143
- "type": "delete",
2144
- "file": "src/utils/oldHelpers.ts",
2145
- "lines": 250,
2146
- "title": "Dead utility functions — no callers in codebase",
2147
- "description": "Entire file is dead code — functions never called. No imports found anywhere.",
2148
- "reason": "No imports found in codebase",
2149
- "roi": "~250 lines"
2150
- },
2151
- {
2152
- "type": "delete",
2153
- "file": "src/legacy/auth.js",
2154
- "lines": 180,
2155
- "title": "Legacy auth replaced by Clerk integration",
2156
- "description": "Legacy auth implementation replaced by Clerk. Migration completed 6 months ago.",
2157
- "reason": "Migration completed 6 months ago",
2158
- "roi": "~180 lines"
2159
- }
2160
- ],
2161
- "mergeItems": [
2162
- {
2163
- "type": "merge",
2164
- "file": "src/utils/validate.ts, src/helpers/validation.ts",
2165
- "title": "Duplicate validation modules",
2166
- "description": "Two files with overlapping validation functions — same Zod schema patterns duplicated",
2167
- "reason": "DRY violation — consolidate into single module",
2168
- "roi": "~120 lines"
2169
- }
2170
- ],
2171
- "simplifyItems": [
2172
- {
2173
- "type": "simplify",
2174
- "file": "src/services/payment.ts",
2175
- "lines": 450,
2176
- "title": "Overly complex payment handler — 450 lines",
2177
- "description": "Single function handles parsing, validation, processing, and error recovery with deeply nested try/catch blocks",
2178
- "reason": "Split into paymentValidator, paymentProcessor, paymentErrorHandler — reduce to ~200 lines",
2179
- "roi": "~250 lines reducible"
2180
- }
2181
- ],
2182
- "totalLinesRemovable": 680,
2183
- "percentageOfCodebase": 4.2
2184
- },
2185
-
2186
- "actionItems": [
2187
- {
2188
- "id": "A-001",
2189
- "title": "Fix SQL injection in user search",
2190
- "priority": "immediate",
2191
- "relatedFindings": ["SEC-001"],
2192
- "effort": "low",
2193
- "description": "Replace string concatenation with parameterized query"
2194
- },
2195
- {
2196
- "id": "A-002",
2197
- "title": "Implement rate limiting on auth endpoints",
2198
- "priority": "immediate",
2199
- "relatedFindings": ["AUTH-003"],
2200
- "effort": "medium",
2201
- "description": "Add Redis-based rate limiter to /login and /register"
2202
- },
2203
- {
2204
- "id": "A-003",
2205
- "title": "Add CSP headers",
2206
- "priority": "high",
2207
- "relatedFindings": ["SEC-005"],
2208
- "effort": "low",
2209
- "description": "Configure helmet with strict CSP policy"
2210
- },
2211
- {
2212
- "id": "A-004",
2213
- "title": "Clean up dead code",
2214
- "priority": "medium",
2215
- "relatedFindings": ["DEAD-001", "DEAD-002"],
2216
- "effort": "medium",
2217
- "description": "Remove 680 lines of unused code identified in quality review"
2218
- },
2219
- {
2220
- "id": "A-005",
2221
- "title": "Implement audit logging",
2222
- "priority": "long-term",
2223
- "relatedFindings": ["DATA-002"],
2224
- "effort": "high",
2225
- "description": "Add comprehensive audit trail for sensitive operations"
2226
- }
2227
- ],
2228
-
2229
- "summary": {
2230
- "total": 10,
2231
- "critical": 1,
2232
- "high": 3,
2233
- "medium": 4,
2234
- "low": 2,
2235
- "info": 0,
2236
- "mitigatedCount": 5,
2237
- "falsePositiveCount": 3,
2238
- "avgConfidence": 0.85
2239
- },
2240
-
2241
142
  "findings": [
2242
143
  {
2243
144
  "id": "SEC-001",
2244
- "title": "SQL Injection in User Search",
145
+ "title": "Specific title describing the exact vulnerability",
2245
146
  "severity": "critical",
2246
147
  "category": "security",
2247
- "file": "src/routes/users.ts",
148
+ "file": "src/routes/user.ts",
2248
149
  "line": 45,
2249
- "code": "db.query(`SELECT * FROM users WHERE name LIKE '%${searchTerm}%'`)",
2250
- "description": "User search parameter is directly concatenated into SQL query without sanitization",
2251
- "impact": "Attacker can extract entire database contents, modify data, or execute system commands",
150
+ "endLine": 52,
151
+ "code": "const query = `SELECT * FROM users WHERE id = ${userId}`",
152
+ "description": "The userId parameter is concatenated directly into the SQL query without sanitization. This allows an attacker to inject arbitrary SQL commands.",
153
+ "impact": "Full database access. Attacker can read all user data, modify records, or delete tables.",
2252
154
  "attackChain": [
2253
- {"step": 1, "action": "Send malicious search term: ' OR '1'='1' --", "result": "Query returns all users"},
2254
- {"step": 2, "action": "Use UNION SELECT to extract data from other tables", "result": "Database schema exposed"},
2255
- {"step": 3, "action": "Extract password hashes and sensitive data", "result": "Full data breach"}
155
+ {"step": 1, "action": "Send userId = '1 OR 1=1'", "result": "Query returns all users"},
156
+ {"step": 2, "action": "Use UNION SELECT to read other tables", "result": "Extract passwords, tokens"},
157
+ {"step": 3, "action": "Use INTO OUTFILE to write webshell", "result": "Remote code execution"}
2256
158
  ],
2257
- "recommendation": "Use parameterized queries: db.query('SELECT * FROM users WHERE name LIKE $1', [`%${searchTerm}%`])",
2258
- "cwe": "CWE-89",
2259
- "owasp": "A03:2021",
2260
- "dreadScore": {
159
+ "recommendation": "Use parameterized queries: `db.query('SELECT * FROM users WHERE id = $1', [userId])`",
160
+ "dread": {
2261
161
  "damage": 10,
2262
162
  "reproducibility": 10,
2263
163
  "exploitability": 9,
2264
164
  "affectedUsers": 10,
2265
165
  "discoverability": 8,
2266
- "total": 9.4
166
+ "score": 9.4
2267
167
  },
2268
- "status": "open",
2269
- "crossReferences": ["T-001"],
2270
- "confidence": 95,
2271
- "fixOwner": "developer",
2272
- "fixType": "code"
2273
- }
2274
- ],
2275
-
2276
- "designDecisions": [
2277
- {
2278
- "id": "DESIGN-001",
2279
- "title": "Content filtering disabled for transparency",
2280
- "file": "src/ai/chat.ts",
2281
- "reason": "Documented decision - users see raw AI output",
2282
- "acceptedRisk": "Users may see inappropriate content"
2283
- }
2284
- ],
2285
-
2286
- "mitigatedFindings": [
2287
- {
2288
- "id": "SEC-005",
2289
- "title": "Original finding title",
2290
- "originalSeverity": "high",
2291
- "reason": "Protected by Zod schema validation at src/routes/user.ts:23",
2292
- "mitigationType": "input_validation"
2293
- }
2294
- ],
2295
-
2296
- "falsePositives": [
2297
- {
2298
- "id": "BIZ-004",
2299
- "title": "TOCTOU Race Condition",
2300
- "reason": "Redis Lua script provides atomic operation - no race condition possible",
2301
- "evidence": ["Lua script at src/services/rate-limit.js:95-113"]
168
+ "cwe": "CWE-89",
169
+ "fixOwner": "developer"
2302
170
  }
2303
171
  ],
2304
-
2305
172
  "positiveObservations": [
2306
173
  {
2307
- "title": "Strong Authentication Implementation",
2308
- "description": "Clerk integration with proper session management, MFA support, and secure cookie settings. All tokens kept server-side. httpOnly + secure cookies with SameSite=strict."
2309
- },
2310
- {
2311
- "title": "Comprehensive Input Validation",
2312
- "description": "Zod schemas used consistently across 15+ API endpoints with proper error handling. Schema-first validation prevents malformed input from reaching business logic."
2313
- },
2314
- {
2315
- "title": "Secure Database Access",
2316
- "description": "Prisma ORM with parameterized queries throughout. Zero raw SQL queries found. Prevents SQL injection across all database operations."
2317
- },
2318
- {
2319
- "title": "Good Error Handling Patterns",
2320
- "description": "Custom AppError class with error codes. Internal details logged server-side only. Generic messages returned to clients. Consistent format across routes."
2321
- }
2322
- ],
2323
-
2324
- "previouslyResolved": [
2325
- {
2326
- "id": "PREV-001",
2327
- "title": "SQL Injection in search endpoint",
2328
- "originalSeverity": "critical",
2329
- "resolution": "Parameterized queries implemented using Prisma ORM. Verified no raw SQL remains.",
2330
- "resolvedDate": "2026-01-15"
174
+ "title": "Proper Password Hashing",
175
+ "description": "Uses bcrypt with cost factor 12 in auth/password.ts:23. Passwords never stored in plaintext."
2331
176
  }
2332
177
  ],
2333
-
2334
- "validationSummary": {
2335
- "totalInitialFindings": 18,
2336
- "mitigated": 5,
2337
- "falsePositives": 3,
2338
- "confirmed": 8,
2339
- "partial": 2,
2340
- "accuracy": "Only 56% of initial findings were actual issues"
178
+ "qualityReview": {
179
+ "deleteItems": [
180
+ {"file": "src/old/legacy.ts", "lines": 250, "description": "Unused legacy code - no imports found"}
181
+ ],
182
+ "mergeItems": [
183
+ {"file": "src/utils/validate.ts + src/helpers/validator.ts", "description": "Duplicate validation logic"}
184
+ ],
185
+ "totalLinesRemovable": 400,
186
+ "percentageOfCodebase": 2.5
2341
187
  },
2342
-
2343
- "agentsUsed": ["Security Core", "Auth & Session", "Mitigation Validator", "Network & Architecture", "Design Decision Detector"],
2344
- "scanDuration": 0
188
+ "summary": {
189
+ "critical": 1,
190
+ "high": 3,
191
+ "medium": 5,
192
+ "low": 2,
193
+ "total": 11
194
+ }
2345
195
  }
2346
196
  ```
2347
197
 
2348
- ### Sanity Check Before Saving
198
+ ### DREAD Scoring (REQUIRED for critical/high):
199
+
200
+ | Score | Meaning |
201
+ |-------|---------|
202
+ | 10 | Worst case |
203
+ | 7-9 | Severe |
204
+ | 4-6 | Moderate |
205
+ | 1-3 | Minor |
206
+
207
+ - **Damage**: Impact if exploited
208
+ - **Reproducibility**: How consistently exploitable
209
+ - **Exploitability**: Skill level needed
210
+ - **Affected Users**: Scope of impact
211
+ - **Discoverability**: How easy to find
212
+ - **Score**: Average of all five
2349
213
 
2350
- Before saving, verify:
2351
- 1. `findings` array does NOT contain any item from `mitigatedFindings` or `falsePositives`
2352
- 2. `summary.total` equals `findings.length`
2353
- 3. Severity counts match actual findings in array
2354
- 4. No duplicate IDs across findings/mitigated/falsePositives
214
+ ### Attack Chain (REQUIRED for critical/high):
2355
215
 
2356
- Save as: .coverme/scan.json
216
+ Show step-by-step exploitation:
217
+ ```json
218
+ [
219
+ {"step": 1, "action": "What attacker does", "result": "What happens"},
220
+ {"step": 2, "action": "Next action", "result": "Escalation"},
221
+ {"step": 3, "action": "Final action", "result": "Full compromise"}
222
+ ]
223
+ ```
2357
224
 
2358
225
  ---
2359
226
 
2360
- ## PHASE 8: GENERATE HTML REPORT (MANDATORY)
227
+ ## PHASE 4: SAVE AND OPEN REPORT
2361
228
 
2362
- **After saving scan.json, you MUST generate and open the HTML report.**
229
+ After creating the JSON, save it and generate HTML:
2363
230
 
2364
- Run this command:
2365
231
  ```bash
2366
- coverme report .coverme/scan.json
232
+ # Save scan.json (you just wrote it)
233
+ # Generate and open HTML report
234
+ coverme report
2367
235
  ```
2368
236
 
2369
- This will:
2370
- 1. Generate `.coverme/report_YYYY-MM-DD_HH-MM-SS.html`
2371
- 2. Automatically open the report in the default browser
237
+ The `coverme report` command will:
238
+ 1. Read `.coverme/scan.json`
239
+ 2. Generate `.coverme/report_YYYY-MM-DD_HH-MM-SS.html`
240
+ 3. Open the report in your browser
2372
241
 
2373
- **If `coverme` command is not available:**
242
+ ---
2374
243
 
2375
- Generate the HTML manually using this template structure, then open it:
2376
- ```bash
2377
- # Save HTML report
2378
- cat > .coverme/report_$(date +%Y-%m-%d_%H-%M-%S).html << 'HTMLEOF'
2379
- <!DOCTYPE html>
2380
- <html>
2381
- <head>
2382
- <title>CoverMe Security Report</title>
2383
- <style>
2384
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }
2385
- .critical { color: #dc2626; } .high { color: #ea580c; } .medium { color: #ca8a04; } .low { color: #16a34a; }
2386
- .finding { border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px; margin: 16px 0; }
2387
- .finding-header { display: flex; justify-content: space-between; align-items: center; }
2388
- pre { background: #f3f4f6; padding: 12px; border-radius: 4px; overflow-x: auto; }
2389
- .summary-card { background: #f9fafb; padding: 20px; border-radius: 8px; margin: 20px 0; }
2390
- </style>
2391
- </head>
2392
- <body>
2393
- <h1>Security Scan Report</h1>
2394
- <!-- Insert findings from scan.json -->
2395
- </body>
2396
- </html>
2397
- HTMLEOF
244
+ ## QUALITY CHECKLIST
2398
245
 
2399
- # Open in browser
2400
- open .coverme/report_*.html 2>/dev/null || xdg-open .coverme/report_*.html 2>/dev/null || echo "Report saved to .coverme/"
2401
- ```
246
+ Before finishing, verify:
2402
247
 
2403
- **CRITICAL**: Do not end the scan without generating and opening the HTML report. The user expects to see the report in their browser.
248
+ - [ ] Read actual code files, not just file names
249
+ - [ ] Every finding has file + line number
250
+ - [ ] Critical/High findings have DREAD scores
251
+ - [ ] Critical/High findings have attack chains
252
+ - [ ] No duplicate findings
253
+ - [ ] Positive observations have specific evidence
254
+ - [ ] Executive summary is professional and specific
255
+ - [ ] `coverme report` was run to generate HTML
2404
256
 
2405
257
  ---
2406
258
 
2407
- ## FINAL STEP - MANDATORY
259
+ ## EXAMPLES
2408
260
 
2409
- After saving `.coverme/scan.json`, you MUST run this command:
261
+ ### Good Finding:
262
+ ```json
263
+ {
264
+ "id": "AUTH-001",
265
+ "title": "JWT accepts 'none' algorithm allowing authentication bypass",
266
+ "severity": "critical",
267
+ "file": "src/middleware/auth.ts",
268
+ "line": 34,
269
+ "code": "jwt.verify(token, secret, { algorithms: ['HS256', 'none'] })",
270
+ "description": "JWT verification accepts the 'none' algorithm. An attacker can forge tokens by removing the signature and setting alg=none.",
271
+ "attackChain": [
272
+ {"step": 1, "action": "Capture valid JWT", "result": "Obtain token structure"},
273
+ {"step": 2, "action": "Decode, modify claims, set alg=none, remove signature", "result": "Forged admin token"},
274
+ {"step": 3, "action": "Send forged token", "result": "Authenticated as any user"}
275
+ ],
276
+ "dread": {"damage": 10, "reproducibility": 10, "exploitability": 9, "affectedUsers": 10, "discoverability": 7, "score": 9.2}
277
+ }
278
+ ```
2410
279
 
2411
- ```bash
2412
- coverme report
280
+ ### Bad Finding (don't do this):
281
+ ```json
282
+ {
283
+ "id": "SEC-001",
284
+ "title": "SQL Injection",
285
+ "severity": "high",
286
+ "description": "There might be SQL injection somewhere"
287
+ }
2413
288
  ```
2414
289
 
2415
- This generates the HTML report and opens it in the browser automatically.
290
+ ---
2416
291
 
2417
- **If you skip this step, the scan is incomplete!**
292
+ ## REMEMBER
2418
293
 
2419
- The scan is only finished when:
2420
- 1. scan.json is saved
2421
- 2. HTML report is generated
2422
- 3. Browser opens with the report
294
+ 1. **Read code before reporting** - Don't guess
295
+ 2. **Be specific** - File names, line numbers, actual code
296
+ 3. **DREAD + Attack Chain** - Required for critical/high
297
+ 4. **Run `coverme report`** - Opens HTML in browser
298
+ 5. **Quality over quantity** - 10 good findings > 50 vague ones