warp-os 1.1.2 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +6 -4
  3. package/VERSION +1 -1
  4. package/agents/warp-annotate.md +394 -0
  5. package/agents/warp-browse.md +9 -1
  6. package/agents/warp-build-code.md +9 -1
  7. package/agents/warp-orchestrator.md +10 -1
  8. package/agents/warp-plan-architect.md +120 -1
  9. package/agents/warp-plan-brainstorm.md +93 -2
  10. package/agents/warp-plan-design.md +97 -4
  11. package/agents/warp-plan-onboarding.md +9 -1
  12. package/agents/warp-plan-optimize.md +9 -1
  13. package/agents/warp-plan-scope.md +67 -1
  14. package/agents/warp-plan-security.md +576 -35
  15. package/agents/warp-plan-testdesign.md +9 -1
  16. package/agents/warp-qa-debug.md +117 -1
  17. package/agents/warp-qa-test.md +167 -1
  18. package/agents/warp-release-update.md +290 -4
  19. package/agents/warp-setup.md +9 -1
  20. package/agents/warp-upgrade.md +21 -4
  21. package/bin/hooks/CLAUDE.md +24 -0
  22. package/bin/hooks/_warp_json.sh +4 -2
  23. package/bin/hooks/identity-briefing.sh +20 -13
  24. package/bin/hooks/validate-askuser.sh +41 -0
  25. package/bin/migrate-sessions.js +284 -173
  26. package/dist/warp-annotate/SKILL.md +404 -0
  27. package/dist/warp-browse/SKILL.md +9 -1
  28. package/dist/warp-build-code/SKILL.md +9 -1
  29. package/dist/warp-orchestrator/SKILL.md +10 -1
  30. package/dist/warp-plan-architect/SKILL.md +120 -1
  31. package/dist/warp-plan-brainstorm/SKILL.md +93 -2
  32. package/dist/warp-plan-design/SKILL.md +97 -4
  33. package/dist/warp-plan-onboarding/SKILL.md +9 -1
  34. package/dist/warp-plan-optimize/SKILL.md +9 -1
  35. package/dist/warp-plan-scope/SKILL.md +67 -1
  36. package/dist/warp-plan-security/SKILL.md +578 -35
  37. package/dist/warp-plan-testdesign/SKILL.md +9 -1
  38. package/dist/warp-qa-debug/SKILL.md +117 -1
  39. package/dist/warp-qa-test/SKILL.md +167 -1
  40. package/dist/warp-release-update/SKILL.md +290 -4
  41. package/dist/warp-setup/SKILL.md +9 -1
  42. package/dist/warp-upgrade/SKILL.md +21 -4
  43. package/package.json +2 -2
  44. package/shared/project-hooks.json +7 -0
  45. package/shared/tier1-engineering-constitution.md +9 -1
@@ -2,10 +2,12 @@
2
2
  name: warp-plan-security
3
3
  description: >
4
4
  Full-spectrum security audit: secrets archaeology, dependency supply chain,
5
+ CI/CD pipeline security, LLM/AI security, skill supply chain scanning,
5
6
  OWASP Top 10, STRIDE threat modeling, static analysis patterns, variant analysis,
6
7
  and fix verification. Inspired by gstack CSO, Trail of Bits security methodology,
7
8
  and skill-threat-modeling. Two modes: daily (fast, high-confidence, 5-10 min) and
8
- comprehensive (full audit, catches everything, 30-60 min).
9
+ comprehensive (full audit, catches everything, 30-60 min). Scope flags for
10
+ targeted audits (--infra, --code, --deps, --diff, --skills, --llm).
9
11
  triggers:
10
12
  - /warp-plan-security
11
13
  - /security
@@ -131,6 +133,8 @@ Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`)
131
133
 
132
134
  ## AskUserQuestion
133
135
 
136
+ **Flow: analysis first, then decision tool.** Present your full reasoning, trade-offs, and recommendations as conversational text — the user wants to read your thinking. Then cap it with AskUserQuestion to formalize the decision. **If you're composing a message with multiple options or "which approach?" language, you MUST end it with AskUserQuestion.** Never present options in prose without the tool.
137
+
134
138
  **Contract:**
135
139
  1. **Re-ground:** Project name, branch, current task. (1-2 sentences.)
136
140
  2. **Simplify:** Plain English a smart 16-year-old could follow.
@@ -152,9 +156,15 @@ Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`)
152
156
  Format: `"Option name — X/10 🟢"` (or 🟡 or 🔴). In the label, not the description.
153
157
  Rate: 🟢 9-10 complete, 🟡 6-8 adequate, 🔴 1-5 shortcuts.
154
158
 
159
+ **Pre-call checklist (verify before every AskUserQuestion invocation):**
160
+ - ☐ Completeness scores in every option label
161
+ - ☐ Recommended option listed first
162
+ - ☐ One decision per question (split if multiple)
163
+ - ☐ Analysis/reasoning already presented in message text above
164
+
155
165
  **Formatting:**
156
166
  - *Italics* for emphasis, not **bold** (bold for headers only).
157
- - After each answer: `✔ Decision {N} recorded [quicksave updated]`
167
+ - After each answer: `✔ Decision {N} recorded`
158
168
  - Previews under 8 lines. Full mockups go in conversation text before the question.
159
169
 
160
170
  ---
@@ -203,22 +213,28 @@ Status values: **DONE**, **DONE_WITH_CONCERNS** (list concerns), **BLOCKED** (st
203
213
  Standalone skill. Runs anytime. Recommended before every `/warp-release-update` and after any dependency change, environment variable addition, or new API endpoint.
204
214
 
205
215
  ```
206
- ┌─────────────────────────────────────────────────────────────┐
207
- WARP-PLAN-SECURITY
208
-
209
- │ Mode: Daily (Phases 1-3) Mode: Comprehensive (1-7)
210
-
211
- Phase 1: Secrets Archaeology
212
- │ Phase 2: Dependency Supply Chain
213
- │ Phase 3: OWASP Top 10
214
- ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
215
- │ Phase 4: STRIDE Threat Model (comprehensive)
216
- │ Phase 5: Static Analysis Patterns (comprehensive)
217
- │ Phase 6: Variant Analysis (comprehensive)
218
- Phase 7: Fix Verification (comprehensive)
219
-
220
- Output: Security audit report (stdout + optional file)
221
- └─────────────────────────────────────────────────────────────┘
216
+ ┌──────────────────────────────────────────────────────────────────┐
217
+ WARP-PLAN-SECURITY
218
+
219
+ │ Mode: Daily (Phases 0-3) Mode: Comprehensive (0-10)
220
+ Scope: --infra --code --deps --diff --skills --llm
221
+
222
+ │ Phase 0: Architecture Mental Model
223
+ │ Phase 0.5: Attack Surface Census
224
+ Phase 1: Secrets Archaeology
225
+ │ Phase 2: Dependency Supply Chain
226
+ │ Phase 2.5: CI/CD Pipeline Security
227
+ │ Phase 3: OWASP Top 10
228
+ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
229
+ Phase 4: STRIDE Threat Model (comprehensive)
230
+ Phase 5: Static Analysis Patterns (comprehensive)
231
+ │ Phase 5.5: LLM & AI Security (comprehensive) │
232
+ │ Phase 5.6: Skill Supply Chain Scanning (comprehensive) │
233
+ │ Phase 6: Variant Analysis (comprehensive) │
234
+ │ Phase 7: Fix Verification (comprehensive) │
235
+ │ │
236
+ │ Output: Security audit report (stdout + optional file) │
237
+ └──────────────────────────────────────────────────────────────────┘
222
238
  ```
223
239
 
224
240
  ---
@@ -263,16 +279,43 @@ Internalize these cognitive patterns. They are not a checklist -- they are how y
263
279
 
264
280
  On invocation, determine the mode:
265
281
 
266
- - If the user says "daily," "quick," "fast," or "scan" --> **Daily mode** (Phases 1-3)
267
- - If the user says "comprehensive," "full," "audit," or "deep" --> **Comprehensive mode** (Phases 1-7)
282
+ - If the user says "daily," "quick," "fast," or "scan" --> **Daily mode** (Phases 0-3)
283
+ - If the user says "comprehensive," "full," "audit," or "deep" --> **Comprehensive mode** (Phases 0-10)
268
284
  - If the user says nothing about mode --> ask:
269
285
 
270
286
  > "Two audit modes available:
271
- > A) **Daily scan** -- high-confidence findings only (8/10 severity bar), runs 5-10 minutes, covers secrets/deps/OWASP
272
- > B) **Comprehensive audit** -- catches everything (2/10 bar), runs 30-60 minutes, adds threat model/static analysis/variant analysis/fix verification
287
+ > A) **Daily scan** -- high-confidence findings only (8/10 severity bar), runs 5-10 minutes, covers architecture model/attack surface/secrets/deps/CI-CD/OWASP
288
+ > B) **Comprehensive audit** -- catches everything (2/10 bar), runs 30-60 minutes, adds threat model/static analysis/LLM security/skill supply chain/variant analysis/fix verification
273
289
  >
274
290
  > RECOMMENDATION: Choose B if this is pre-ship, first audit, or after major changes. Choose A for routine checks."
275
291
 
292
+ ### Scope Flags
293
+
294
+ Support targeted audits via scope flags. When a scope flag is provided, run ONLY the matching phases (plus Phase 0 for context). Multiple flags can be combined.
295
+
296
+ | Flag | Phases Run | What It Covers |
297
+ |------|-----------|----------------|
298
+ | `--infra` | 0, 0.5, 2.5 (CI/CD) | CI/CD pipelines, Docker, IaC configs only |
299
+ | `--code` | 0, 3 (OWASP), 5 (Static Analysis) | OWASP Top 10, static analysis patterns only |
300
+ | `--deps` | 0, 2 (Dependency Supply Chain) | Dependency supply chain only |
301
+ | `--diff` | 0, then all phases scoped to changed files | Only scan files changed since last audit |
302
+ | `--skills` | 0, 5.6 (Skill Supply Chain) | Claude Code skill supply chain only |
303
+ | `--llm` | 0, 5.5 (LLM & AI Security) | LLM/AI security vectors only |
304
+
305
+ When `--diff` is used, determine the changed file set:
306
+ ```bash
307
+ # If a previous audit report exists, diff since that commit
308
+ LAST_AUDIT_COMMIT=$(git log --all --oneline --grep="Security Audit" --format='%H' | head -1)
309
+ if [ -n "$LAST_AUDIT_COMMIT" ]; then
310
+ git diff --name-only "$LAST_AUDIT_COMMIT"..HEAD
311
+ else
312
+ # Fall back to last 7 days
313
+ git diff --name-only "HEAD@{7 days ago}"..HEAD 2>/dev/null || git diff --name-only HEAD~20..HEAD
314
+ fi
315
+ ```
316
+
317
+ Only scan those files in each phase. Report the diff scope in the audit header.
318
+
276
319
  ### Severity Bar
277
320
 
278
321
  - **Daily mode (8/10 bar):** Only report findings that are HIGH or CRITICAL severity. These are things that an attacker could exploit today with minimal effort. Skip informational, low, and medium findings -- they create noise that delays shipping.
@@ -295,6 +338,142 @@ On invocation, determine the mode:
295
338
 
296
339
  ---
297
340
 
341
+ ## PHASE 0: Architecture Mental Model
342
+
343
+ **Goal:** Before scanning anything, build a mental model of the application's technology stack, deployment model, and integration points. This model determines which subsequent phases are relevant and which can be skipped.
344
+
345
+ **Time budget:** Daily 1-2 min, Comprehensive 2-3 min.
346
+
347
+ ### 0A. Technology Detection
348
+
349
+ Scan project root for configuration files that reveal the stack:
350
+
351
+ ```bash
352
+ # Detect language/runtime
353
+ for f in package.json Cargo.toml go.mod pyproject.toml requirements.txt Gemfile pom.xml build.gradle composer.json; do
354
+ [ -f "$f" ] && echo "FOUND: $f"
355
+ done
356
+
357
+ # Detect framework
358
+ git grep -l -E '(next\.config|nuxt\.config|remix\.config|vite\.config|angular\.json|svelte\.config)' -- ':!node_modules' 2>/dev/null | head -5
359
+ git grep -l -E '(from ["\x27]express|from ["\x27]fastify|from ["\x27]hono|from ["\x27]django|from ["\x27]flask|from ["\x27]rails)' -- ':!node_modules' 2>/dev/null | head -5
360
+
361
+ # Detect database
362
+ git grep -l -E '(prisma|drizzle|typeorm|sequelize|knex|mongoose|supabase|firebase)' -- '*.json' '*.ts' '*.js' ':!node_modules' 2>/dev/null | head -5
363
+
364
+ # Detect auth
365
+ git grep -l -E '(next-auth|passport|jwt|jsonwebtoken|bcrypt|argon2|oauth|clerk|auth0|supabase.*auth)' -- '*.json' '*.ts' '*.js' ':!node_modules' 2>/dev/null | head -5
366
+
367
+ # Detect deployment
368
+ for f in Dockerfile docker-compose.yml fly.toml vercel.json netlify.toml render.yaml serverless.yml terraform.tf; do
369
+ [ -f "$f" ] && echo "DEPLOY: $f"
370
+ done
371
+ find . -name "*.tf" -not -path "*/node_modules/*" -maxdepth 3 2>/dev/null | head -5
372
+ ```
373
+
374
+ ### 0B. Mental Model Output
375
+
376
+ Produce this structured summary before proceeding:
377
+
378
+ ```
379
+ ARCHITECTURE MENTAL MODEL:
380
+ Language/Runtime: [detected from package.json, Cargo.toml, etc.]
381
+ Framework: [Next.js, Express, Django, Rails, etc.]
382
+ Database: [Postgres, MySQL, SQLite, none]
383
+ Auth: [JWT, session, OAuth, none detected]
384
+ External integrations: [list APIs, webhooks, third-party services]
385
+ Deployment: [Docker, serverless, bare metal, PaaS]
386
+
387
+ This mental model guides which phases are relevant and which can be skipped.
388
+ ```
389
+
390
+ ### 0C. Phase Relevance
391
+
392
+ Based on the mental model, note which phases need extra attention:
393
+ - No auth detected --> Phase 3 A01 and A07 are top priority
394
+ - Docker/CI detected --> Phase 2.5 is critical
395
+ - LLM/AI dependencies detected --> Phase 5.5 is critical
396
+ - Claude Code skills installed --> Phase 5.6 is critical
397
+ - External integrations detected --> STRIDE trust boundary analysis is critical
398
+ - No database detected --> skip database-specific checks in OWASP
399
+
400
+ ---
401
+
402
+ ## PHASE 0.5: Attack Surface Census
403
+
404
+ **Goal:** Produce a quantitative map of the application's attack surface. Higher numbers mean larger surface area requiring more scrutiny.
405
+
406
+ **Time budget:** Daily 1-2 min, Comprehensive 3-5 min.
407
+
408
+ ### 0.5A. Surface Enumeration
409
+
410
+ ```bash
411
+ # Count public endpoints (no auth middleware)
412
+ echo "=== Endpoint counts ==="
413
+ PUBLIC=$(git grep -c -E '(app\.(get|post|put|patch|delete)|router\.(get|post|put|patch|delete)|export.*(GET|POST|PUT|PATCH|DELETE))' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | awk -F: '{s+=$2} END {print s+0}')
414
+ echo "Route definitions: $PUBLIC"
415
+
416
+ # Count file upload handlers
417
+ UPLOADS=$(git grep -c -E '(multer|upload|formidable|busboy|multipart)' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | awk -F: '{s+=$2} END {print s+0}')
418
+ echo "File upload references: $UPLOADS"
419
+
420
+ # Count WebSocket channels
421
+ WS=$(git grep -c -E '(WebSocket|socket\.io|ws\(|wss://|io\.on)' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | awk -F: '{s+=$2} END {print s+0}')
422
+ echo "WebSocket references: $WS"
423
+
424
+ # Count external integrations
425
+ EXT=$(git grep -c -E '(fetch|axios|http\.get|https\.get)\s*\(' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | awk -F: '{s+=$2} END {print s+0}')
426
+ echo "External HTTP calls: $EXT"
427
+
428
+ # Count background jobs
429
+ JOBS=$(git grep -c -E '(cron|schedule|setInterval|bull|agenda|bree|node-cron)' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | awk -F: '{s+=$2} END {print s+0}')
430
+ echo "Background job references: $JOBS"
431
+
432
+ # Count CI/CD workflows
433
+ CI=$(find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | wc -l)
434
+ echo "CI/CD workflow files: $CI"
435
+
436
+ # Count webhook receivers
437
+ HOOKS=$(git grep -c -E '(webhook|/hook|/callback|/notify)' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | awk -F: '{s+=$2} END {print s+0}')
438
+ echo "Webhook references: $HOOKS"
439
+
440
+ # Count container configs
441
+ CONTAINERS=$(find . \( -name "Dockerfile*" -o -name "docker-compose*.yml" -o -name ".dockerignore" \) -not -path "*/node_modules/*" 2>/dev/null | wc -l)
442
+ echo "Container config files: $CONTAINERS"
443
+
444
+ # Count IaC configs
445
+ IAC=$(find . \( -name "*.tf" -o -name "*.tfvars" -o -name "serverless.yml" -o -name "cdk.json" -o -name "pulumi.*" \) -not -path "*/node_modules/*" 2>/dev/null | wc -l)
446
+ echo "IaC config files: $IAC"
447
+ ```
448
+
449
+ ### 0.5B. Census Output
450
+
451
+ ```
452
+ ATTACK SURFACE CENSUS:
453
+ ┌────────────────────────┬───────┐
454
+ │ Surface │ Count │
455
+ ├────────────────────────┼───────┤
456
+ │ Public endpoints │ [N] │
457
+ │ Authenticated endpoints │ [N] │
458
+ │ Admin-only endpoints │ [N] │
459
+ │ File upload points │ [N] │
460
+ │ WebSocket channels │ [N] │
461
+ │ External integrations │ [N] │
462
+ │ Background jobs │ [N] │
463
+ │ CI/CD workflows │ [N] │
464
+ │ Webhook receivers │ [N] │
465
+ │ Container configs │ [N] │
466
+ │ IaC configs │ [N] │
467
+ └────────────────────────┴───────┘
468
+ Higher counts = larger attack surface = more scrutiny needed.
469
+ ```
470
+
471
+ Use these counts to allocate time in subsequent phases. A project with 50 endpoints and 0 CI/CD workflows should spend 80% of time on code phases and skip CI/CD. A project with 2 endpoints and 15 CI/CD workflows should prioritize infrastructure.
472
+
473
+ **SOFT GATE: Mental model and attack surface census complete. Proceed to secrets archaeology.**
474
+
475
+ ---
476
+
298
477
  ## PHASE 1: Secrets Archaeology
299
478
 
300
479
  **Goal:** Find every secret that has ever been committed, is currently exposed, or could leak through misconfiguration.
@@ -508,6 +687,110 @@ find node_modules -name "binding.gyp" -maxdepth 3 2>/dev/null | head -10
508
687
 
509
688
  ---
510
689
 
690
+ ## PHASE 2.5: CI/CD Pipeline Security
691
+
692
+ **Goal:** Audit CI/CD pipelines for supply chain attacks, secret exfiltration, and privilege escalation. CI/CD pipelines have production credentials, deployment access, and signing keys -- they are the single highest-value target in most organizations.
693
+
694
+ **Time budget:** Daily 2-3 min, Comprehensive 5-10 min.
695
+
696
+ ### 2.5A. GitHub Actions Audit
697
+
698
+ ```bash
699
+ # Find all workflow files
700
+ find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | while read f; do
701
+ echo "=== $f ==="
702
+
703
+ # Check for unpinned third-party actions (uses tag instead of SHA)
704
+ echo "--- Unpinned actions (should use SHA, not tag) ---"
705
+ grep -n 'uses:' "$f" | grep -v -E '@[0-9a-f]{40}' | grep -v 'actions/(checkout|setup-node|cache|upload-artifact|download-artifact)@v' | head -10
706
+
707
+ # Check for dangerous triggers
708
+ echo "--- Dangerous triggers ---"
709
+ grep -n 'pull_request_target' "$f" | head -5
710
+ grep -n 'workflow_dispatch' "$f" | head -5
711
+
712
+ # Check for script injection via interpolation in run: blocks
713
+ echo "--- Potential script injection ---"
714
+ grep -n -E '\$\{\{\s*github\.event\.(issue|pull_request|comment|review|discussion)\.' "$f" | head -10
715
+
716
+ # Check for overly broad secret access
717
+ echo "--- Secret usage ---"
718
+ grep -n -E 'secrets\.' "$f" | head -10
719
+ done
720
+ ```
721
+
722
+ ### 2.5B. Specific CI/CD Checks
723
+
724
+ **Unpinned third-party actions:**
725
+ Third-party GitHub Actions referenced by tag (`@v1`, `@main`) can be silently updated by the action author to inject malicious code. Pin to a full commit SHA (`@a1b2c3d...`).
726
+
727
+ ```
728
+ FINDING template:
729
+ Unpinned action: [action@tag]
730
+ Workflow: [file:line]
731
+ Risk: Action author can push malicious code that runs with your repo's permissions
732
+ Fix: Pin to SHA: [action@full-sha] (find SHA at the action's releases page)
733
+ ```
734
+
735
+ **`pull_request_target` trigger:**
736
+ This trigger runs in the context of the BASE branch, with access to base branch secrets. A malicious PR can exfiltrate secrets if the workflow checks out PR code and runs it. This is one of the most dangerous GitHub Actions patterns.
737
+
738
+ ```bash
739
+ # Check if pull_request_target workflows check out PR code (the dangerous pattern)
740
+ for f in .github/workflows/*.yml .github/workflows/*.yaml; do
741
+ [ -f "$f" ] || continue
742
+ if grep -q 'pull_request_target' "$f"; then
743
+ echo "=== $f uses pull_request_target ==="
744
+ # Does it also checkout PR head? (the exploit vector)
745
+ grep -n -E 'ref.*\$\{\{ github.event.pull_request.head' "$f" | head -5
746
+ grep -n -E 'ref.*\$\{\{ github.head_ref' "$f" | head -5
747
+ fi
748
+ done
749
+ ```
750
+
751
+ **Script injection via expression interpolation:**
752
+ When `${{ github.event.issue.title }}` or similar expressions appear in `run:` blocks, an attacker can craft an issue title containing shell commands that execute in the workflow.
753
+
754
+ ```bash
755
+ # Find all interpolated expressions in run: blocks
756
+ for f in .github/workflows/*.yml .github/workflows/*.yaml; do
757
+ [ -f "$f" ] || continue
758
+ # Look for github.event context used in run blocks (potential injection)
759
+ grep -n -B2 -A2 '\$\{\{.*github\.event\.' "$f" 2>/dev/null | grep -A2 'run:' | head -20
760
+ done
761
+ ```
762
+
763
+ **Secrets passed to unnecessary steps:**
764
+ Each workflow step should only receive the secrets it needs. Steps that receive all secrets via `env:` at the job level can exfiltrate secrets they do not need.
765
+
766
+ **CODEOWNERS protection:**
767
+ ```bash
768
+ # Check if CODEOWNERS exists and what it protects
769
+ if [ -f "CODEOWNERS" ] || [ -f ".github/CODEOWNERS" ] || [ -f "docs/CODEOWNERS" ]; then
770
+ echo "CODEOWNERS found:"
771
+ cat CODEOWNERS .github/CODEOWNERS docs/CODEOWNERS 2>/dev/null
772
+ echo ""
773
+ echo "Check: Is branch protection enabled requiring CODEOWNERS review?"
774
+ else
775
+ echo "WARN: No CODEOWNERS file found"
776
+ fi
777
+ ```
778
+
779
+ **Self-hosted runner risks:**
780
+ ```bash
781
+ # Check for self-hosted runner usage
782
+ for f in .github/workflows/*.yml .github/workflows/*.yaml; do
783
+ [ -f "$f" ] || continue
784
+ grep -n 'runs-on.*self-hosted' "$f" | head -5
785
+ done
786
+ ```
787
+
788
+ Self-hosted runners can access other workflows' secrets, persist state between jobs, and provide lateral movement to the host machine's network. If found, flag as HIGH and recommend ephemeral runners or container isolation.
789
+
790
+ **SOFT GATE: Phase 2.5 complete. Proceed to OWASP Top 10.**
791
+
792
+ ---
793
+
511
794
  ## PHASE 3: OWASP Top 10
512
795
 
513
796
  **Goal:** Systematically check for all OWASP Top 10 (2021) vulnerability categories in the codebase.
@@ -688,9 +971,9 @@ git grep -n -E '(url\.parse|new URL|redirect|location)' -- '*.ts' '*.js' ':!node
688
971
  - Internal network addresses (10.x, 172.16.x, 192.168.x, 127.x, localhost) are blocked in user-supplied URLs
689
972
  - Redirect endpoints validate the target URL
690
973
 
691
- **HARD GATE (Daily mode): Phases 1-3 complete. Present findings summary. In daily mode, this is the final gate -- produce the report.**
974
+ **HARD GATE (Daily mode): Phases 0-3 complete. Present findings summary. In daily mode, this is the final gate -- produce the report.**
692
975
 
693
- **SOFT GATE (Comprehensive mode): Phases 1-3 complete. Proceed to Phase 4.**
976
+ **SOFT GATE (Comprehensive mode): Phases 0-3 complete. Proceed to Phase 4.**
694
977
 
695
978
  ---
696
979
 
@@ -888,7 +1171,205 @@ Apply common vulnerability patterns. For each pattern, search the codebase:
888
1171
  | Mass assignment | Spreading user input into DB write | `git grep -n 'insert.*\.\.\.req\|update.*\.\.\.body\|create.*\.\.\.input'` |
889
1172
  | Timing attack | Non-constant-time comparison of secrets | `git grep -n '===.*token\|===.*secret\|===.*hash'` |
890
1173
 
891
- **SOFT GATE: Phase 5 complete. Proceed to variant analysis.**
1174
+ **SOFT GATE: Phase 5 complete. Proceed to LLM & AI security.**
1175
+
1176
+ ---
1177
+
1178
+ ## PHASE 5.5: LLM & AI Security
1179
+
1180
+ **Comprehensive mode only.**
1181
+
1182
+ **Goal:** Audit all LLM/AI integration points for prompt injection, output trust violations, key exposure, and unsafe execution patterns.
1183
+
1184
+ **Time budget:** 5-10 min.
1185
+
1186
+ ### 5.5A. LLM Integration Detection
1187
+
1188
+ ```bash
1189
+ # Detect LLM/AI SDKs and API usage
1190
+ git grep -l -E '(openai|anthropic|@anthropic-ai|langchain|llama|cohere|replicate|huggingface|ai/core|@ai-sdk)' -- '*.ts' '*.js' '*.py' '*.json' ':!node_modules' ':!*.lock' 2>/dev/null | head -20
1191
+
1192
+ # Detect prompt construction
1193
+ git grep -n -E '(system.*prompt|user.*prompt|messages.*role|ChatCompletion|generateText|streamText|createChat)' -- '*.ts' '*.js' '*.py' ':!node_modules' 2>/dev/null | head -30
1194
+
1195
+ # Detect tool/function calling
1196
+ git grep -n -E '(tools|functions|function_call|tool_choice|tool_use)' -- '*.ts' '*.js' '*.py' ':!node_modules' 2>/dev/null | head -20
1197
+ ```
1198
+
1199
+ ### 5.5B. Prompt Injection Vectors
1200
+
1201
+ Check every code path where user input feeds into LLM prompts:
1202
+
1203
+ ```bash
1204
+ # Find prompt templates with interpolated user input
1205
+ git grep -n -E '(prompt.*\$\{|prompt.*\+|`.*\$\{.*user|`.*\$\{.*input|`.*\$\{.*query|`.*\$\{.*message)' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | head -20
1206
+
1207
+ # Find f-strings or format strings in prompt construction (Python)
1208
+ git grep -n -E '(f["\x27].*\{.*user|f["\x27].*\{.*input|\.format\(.*user|\.format\(.*input)' -- '*.py' ':!node_modules' 2>/dev/null | head -20
1209
+ ```
1210
+
1211
+ **Specific checks:**
1212
+ - User input concatenated directly into system prompts without sanitization or delimiters
1213
+ - User input placed before system instructions (allows instruction override)
1214
+ - No input length limits on user content sent to LLM (cost and injection risk)
1215
+ - Missing output validation before rendering LLM responses
1216
+
1217
+ ### 5.5C. Unsanitized LLM Output
1218
+
1219
+ LLM output is UNTRUSTED. It must be treated like user input at every rendering boundary.
1220
+
1221
+ ```bash
1222
+ # LLM output rendered as HTML (XSS via LLM)
1223
+ git grep -n -E '(dangerouslySetInnerHTML|v-html|innerHTML)' -- '*.ts' '*.tsx' '*.js' '*.jsx' '*.vue' ':!node_modules' 2>/dev/null | head -10
1224
+
1225
+ # LLM output used in SQL (injection via LLM)
1226
+ git grep -n -E '(query|execute|raw)\s*\(' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | head -10
1227
+
1228
+ # LLM output used in shell commands (command injection via LLM)
1229
+ git grep -n -E '(exec|spawn|execSync|child_process)' -- '*.ts' '*.js' ':!node_modules' 2>/dev/null | head -10
1230
+
1231
+ # eval/exec of LLM output (arbitrary code execution)
1232
+ git grep -n -E '(eval|exec|Function)\s*\(' -- '*.ts' '*.js' '*.py' ':!node_modules' 2>/dev/null | head -15
1233
+ ```
1234
+
1235
+ Cross-reference these with LLM output variables. If LLM output flows into any of these sinks without sanitization, it is a finding.
1236
+
1237
+ ### 5.5D. Tool/Function Calling Validation
1238
+
1239
+ If the application uses LLM tool/function calling:
1240
+
1241
+ **Specific checks:**
1242
+ - Are tool calls from the LLM validated against an allowlist before execution?
1243
+ - Are tool call arguments validated/sanitized before being passed to the actual function?
1244
+ - Can the LLM request tools that access sensitive resources (file system, database, network)?
1245
+ - Is there a human-in-the-loop for destructive tool calls?
1246
+ - Are tool results from external sources sanitized before being fed back to the LLM?
1247
+
1248
+ ### 5.5E. AI API Key Security
1249
+
1250
+ ```bash
1251
+ # Hardcoded AI API keys
1252
+ git grep -n -E '(sk-[a-zA-Z0-9]{20,}|sk-ant-[a-zA-Z0-9]{20,}|sk-proj-[a-zA-Z0-9]{20,})' -- ':!node_modules' ':!*.lock' 2>/dev/null | head -10
1253
+
1254
+ # AI keys in committed env files
1255
+ git log --all -p --diff-filter=A -- '*.env' '*.env.*' 2>/dev/null | grep -E '(OPENAI|ANTHROPIC|COHERE|REPLICATE|HUGGINGFACE).*=' | head -10
1256
+
1257
+ # AI keys in client-side code (prefix patterns)
1258
+ git grep -n -E '(NEXT_PUBLIC|EXPO_PUBLIC|REACT_APP|VITE_).*(OPENAI|ANTHROPIC|AI_|LLM_)' -- ':!*.md' 2>/dev/null | head -10
1259
+ ```
1260
+
1261
+ ### 5.5F. LLM Rate Limiting and Availability
1262
+
1263
+ **Specific checks:**
1264
+ - Rate limiting on endpoints that trigger LLM API calls (prevent cost abuse)
1265
+ - Timeout handling for LLM API calls (prevent request queuing)
1266
+ - Fallback behavior when LLM API is unavailable (graceful degradation, not crash)
1267
+ - Cost controls or budget limits on LLM API usage
1268
+ - Retry logic that could amplify costs on failure
1269
+
1270
+ **SOFT GATE: Phase 5.5 complete. Proceed to skill supply chain scanning.**
1271
+
1272
+ ---
1273
+
1274
+ ## PHASE 5.6: Skill Supply Chain Scanning
1275
+
1276
+ **Comprehensive mode only.**
1277
+
1278
+ **Goal:** Audit installed Claude Code skills (and similar agent tools) for malicious behavior, data exfiltration, and prompt injection. Research shows 36% of published skills have security flaws, and 13.4% are outright malicious (gstack research).
1279
+
1280
+ **Time budget:** 5-10 min.
1281
+
1282
+ ### 5.6A. Skill Inventory
1283
+
1284
+ ```bash
1285
+ # List installed Claude Code skills
1286
+ ls -la ~/.claude/skills/ 2>/dev/null | head -30
1287
+
1288
+ # List installed agents
1289
+ ls -la ~/.claude/agents/ 2>/dev/null | head -30
1290
+
1291
+ # Check project-local skills
1292
+ find . -path '*/.claude/skills/*' -name "*.md" -not -path "*/node_modules/*" 2>/dev/null | head -20
1293
+
1294
+ # Check for hook scripts
1295
+ cat .claude/settings.json 2>/dev/null | grep -A5 '"hooks"' | head -20
1296
+ cat .claude/settings.local.json 2>/dev/null | grep -A5 '"hooks"' | head -20
1297
+ ```
1298
+
1299
+ ### 5.6B. Network Exfiltration Patterns
1300
+
1301
+ Scan all skill and hook files for outbound network calls:
1302
+
1303
+ ```bash
1304
+ # Check hook scripts for network calls
1305
+ find .claude -name "*.sh" -o -name "*.js" -o -name "*.py" 2>/dev/null | while read f; do
1306
+ echo "=== $f ==="
1307
+ grep -n -E '(curl|wget|fetch|http|https|XMLHttpRequest|net\.Socket|dgram)' "$f" 2>/dev/null | head -5
1308
+ done
1309
+
1310
+ # Check skill definitions for network instruction patterns
1311
+ find ~/.claude/skills -name "*.md" 2>/dev/null | while read f; do
1312
+ HITS=$(grep -c -i -E '(send.*to|post.*to|upload.*to|exfiltrate|phone.*home|beacon|ping.*server)' "$f" 2>/dev/null)
1313
+ if [ "$HITS" -gt 0 ]; then
1314
+ echo "SUSPICIOUS: $f ($HITS network instruction patterns)"
1315
+ fi
1316
+ done
1317
+ ```
1318
+
1319
+ ### 5.6C. Credential Access Patterns
1320
+
1321
+ ```bash
1322
+ # Check for scripts reading sensitive directories
1323
+ find .claude -name "*.sh" -o -name "*.js" -o -name "*.py" 2>/dev/null | while read f; do
1324
+ echo "=== $f ==="
1325
+ grep -n -E '(\.ssh/|\.aws/|\.gnupg/|\.npmrc|\.pypirc|\.netrc|\.docker/config|credentials|keychain)' "$f" 2>/dev/null | head -5
1326
+ grep -n -E '(process\.env|os\.environ|ENV\[|getenv)' "$f" 2>/dev/null | head -5
1327
+ done
1328
+ ```
1329
+
1330
+ ### 5.6D. Prompt Injection in Skill Definitions
1331
+
1332
+ Check skill definitions for prompt injection patterns:
1333
+
1334
+ ```bash
1335
+ # Look for instruction override attempts in skill files
1336
+ find ~/.claude/skills -name "*.md" 2>/dev/null | while read f; do
1337
+ grep -n -i -E '(ignore.*previous|disregard.*instructions|override.*system|you are now|forget.*rules|new instructions)' "$f" 2>/dev/null | head -3
1338
+ [ $? -eq 0 ] && echo "SUSPICIOUS prompt injection pattern in: $f"
1339
+ done
1340
+ ```
1341
+
1342
+ ### 5.6E. Obfuscated Code Detection
1343
+
1344
+ ```bash
1345
+ # Check hook scripts for obfuscation patterns
1346
+ find .claude -name "*.sh" -o -name "*.js" -o -name "*.py" 2>/dev/null | while read f; do
1347
+ echo "=== $f ==="
1348
+ # Base64 encoded commands
1349
+ grep -n -E '(base64|atob|btoa|decode\(|b64decode)' "$f" 2>/dev/null | head -3
1350
+ # Hex-encoded strings
1351
+ grep -n -E '\\x[0-9a-fA-F]{2}.*\\x[0-9a-fA-F]{2}.*\\x[0-9a-fA-F]{2}' "$f" 2>/dev/null | head -3
1352
+ # eval with encoded input
1353
+ grep -n -E '(eval|exec)\s*\(.*decode' "$f" 2>/dev/null | head -3
1354
+ done
1355
+ ```
1356
+
1357
+ ### 5.6F. Skill Risk Classification
1358
+
1359
+ For each skill/agent found:
1360
+
1361
+ ```
1362
+ SKILL: [name]
1363
+ Source: [official | community | unknown]
1364
+ Network access: [none | detected (list URLs)]
1365
+ Credential access: [none | detected (list paths)]
1366
+ Prompt injection: [none | suspicious patterns found]
1367
+ Obfuscation: [none | detected]
1368
+ Risk: [LOW | MEDIUM | HIGH | CRITICAL]
1369
+ Recommendation: [keep | review | remove]
1370
+ ```
1371
+
1372
+ **SOFT GATE: Phase 5.6 complete. Proceed to variant analysis.**
892
1373
 
893
1374
  ---
894
1375
 
@@ -935,7 +1416,22 @@ VARIANT: [location file:line]
935
1416
  Severity delta: [same as original | higher because... | lower because...]
936
1417
  ```
937
1418
 
938
- ### 6D. Systemic Issue Identification
1419
+ ### 6D. Variant Analysis Output
1420
+
1421
+ When a finding is VERIFIED in any phase, produce this structured output for every variant search:
1422
+
1423
+ ```
1424
+ VARIANT ANALYSIS:
1425
+ Finding: [description of the original verified finding]
1426
+ Pattern: [regex or code pattern used to search]
1427
+ Codebase scan results: [N additional instances found]
1428
+ Locations: [file:line for each instance]
1429
+ Exploitability per location: [yes/no/uncertain for each]
1430
+ ```
1431
+
1432
+ This output is mandatory for every CRITICAL and HIGH finding. For MEDIUM and below, variant analysis is recommended but not required.
1433
+
1434
+ ### 6E. Systemic Issue Identification
939
1435
 
940
1436
  If 3+ variants of the same pattern are found:
941
1437
 
@@ -1071,7 +1567,7 @@ For daily mode, sections marked [COMPREHENSIVE] are omitted.
1071
1567
 
1072
1568
  ## [COMPREHENSIVE] Systemic Issues
1073
1569
 
1074
- {From Phase 6D -- patterns that recur across the codebase}
1570
+ {From Phase 6E -- patterns that recur across the codebase}
1075
1571
 
1076
1572
  ## Fix Priority Matrix
1077
1573
 
@@ -1090,10 +1586,43 @@ For daily mode, sections marked [COMPREHENSIVE] are omitted.
1090
1586
 
1091
1587
  ## Trend Tracking
1092
1588
 
1093
- {If previous audit reports exist, compare:}
1589
+ {If previous audit reports exist in `.warp/reports/planning/`, compare:}
1590
+
1591
+ TREND COMPARISON:
1592
+ Previous audit: [date] — [N] findings
1593
+ Current audit: [date] — [N] findings
1594
+ Resolved since last: [N] — [list]
1595
+ Persistent (still open): [N] — [list]
1596
+ New (first seen): [N] — [list]
1597
+ Trend: IMPROVING | STABLE | DEGRADING
1598
+
1094
1599
  - Findings resolved since last audit: {list}
1095
1600
  - New findings since last audit: {list}
1096
1601
  - Recurring findings (appeared in 2+ audits): {list} — these need systemic fixes
1602
+ - Trend direction: IMPROVING (fewer findings) | STABLE (same count) | DEGRADING (more findings)
1603
+
1604
+ ## Attack Surface Census
1605
+
1606
+ {From Phase 0.5 — the quantitative attack surface map}
1607
+
1608
+ ## [COMPREHENSIVE] Data Classification
1609
+
1610
+ {From Phase 4 data flow analysis — the four-tier data classification table}
1611
+
1612
+ ## [COMPREHENSIVE] LLM & AI Security Summary
1613
+
1614
+ {From Phase 5.5 — prompt injection vectors, output trust violations, API key findings}
1615
+
1616
+ ## [COMPREHENSIVE] Skill Supply Chain Summary
1617
+
1618
+ {From Phase 5.6 — risk classification for each installed skill/agent}
1619
+
1620
+ ---
1621
+
1622
+ DISCLAIMER: This automated security audit is not a substitute for a professional
1623
+ penetration test or security assessment. It identifies common vulnerability patterns
1624
+ but cannot guarantee completeness. For production systems handling sensitive data,
1625
+ engage a professional security firm.
1097
1626
  ```
1098
1627
 
1099
1628
  ---
@@ -1104,12 +1633,26 @@ These principles are architectural, not tactical. They shape how the system is d
1104
1633
 
1105
1634
  **Default deny.** New endpoints, resources, and operations are inaccessible until permissions are explicitly defined. The default state of any new surface area is "blocked." Access must be granted, never assumed. If a developer adds a new API endpoint and forgets to add an auth check, the default-deny architecture rejects all requests to it rather than serving them to anyone.
1106
1635
 
1107
- **Three-tier data classification.** All data in the system belongs to one of three tiers:
1108
- - **Public:** Safe to expose to any user or external system. Example: app version, public documentation.
1109
- - **Sensitive:** Accessible only to authenticated users with appropriate authorization. Example: user profile, flight schedule, notification preferences.
1110
- - **Restricted:** Accessible only to specific roles with audit logging. Example: service role keys, admin credentials, PII aggregates.
1636
+ **Four-tier data classification.** All data in the system belongs to one of four tiers. In comprehensive audits, produce the data classification table as part of Phase 4 (STRIDE) data flow analysis:
1637
+
1638
+ ```
1639
+ DATA CLASSIFICATION:
1640
+ ┌────────────────┬─────────────┬──────────────────────────────┐
1641
+ │ Data │ Class │ Handling Requirements │
1642
+ ├────────────────┼─────────────┼──────────────────────────────┤
1643
+ │ [data type] │ RESTRICTED │ Encrypted at rest + in transit │
1644
+ │ [data type] │ CONFIDENTIAL │ Access-controlled, logged │
1645
+ │ [data type] │ INTERNAL │ Not public, basic controls │
1646
+ │ [data type] │ PUBLIC │ No restrictions │
1647
+ └────────────────┴─────────────┴──────────────────────────────┘
1648
+ ```
1649
+
1650
+ - **PUBLIC:** Safe to expose to any user or external system. Example: app version, public documentation.
1651
+ - **INTERNAL:** Not public, but low sensitivity. Basic access controls. Example: internal feature flags, non-sensitive configuration.
1652
+ - **CONFIDENTIAL:** Accessible only to authenticated users with appropriate authorization. Example: user profile, flight schedule, notification preferences.
1653
+ - **RESTRICTED:** Accessible only to specific roles with audit logging. Encrypted at rest and in transit. Example: service role keys, admin credentials, PII aggregates, payment data.
1111
1654
 
1112
- Every data field in the architecture should be classifiable into one of these tiers. If a field's tier is ambiguous, treat it as Sensitive until explicitly classified.
1655
+ Every data field in the architecture should be classifiable into one of these tiers. If a field's tier is ambiguous, treat it as CONFIDENTIAL until explicitly classified. The classification table is a required output in comprehensive mode -- it goes in the report alongside the STRIDE threat model.
1113
1656
 
1114
1657
  **Design for most restrictive phase, enforce from earliest.** If the product will eventually need HIPAA compliance, SOC 2, or GDPR data residency — design for those constraints now, even if enforcement is deferred. Retrofitting security constraints into an architecture designed without them costs 10x the effort of building them in from the start. No shortcuts that require retrofit.
1115
1658
 
@@ -1145,7 +1688,7 @@ These are security review anti-patterns. If you catch yourself doing any of thes
1145
1688
 
1146
1689
  1. **MUST redact all secret values in report output.** Never print actual API keys, passwords, tokens, or credentials. Use `[REDACTED]` or show only the first 4 characters.
1147
1690
 
1148
- 2. **MUST run Phase 1 (Secrets Archaeology) first in every audit.** Secrets leaks are the highest-ROI finding for an attacker and take minutes to check.
1691
+ 2. **MUST run Phase 0 (Architecture Mental Model) and Phase 1 (Secrets Archaeology) in every audit.** Phase 0 builds the context model. Phase 1 (secrets) is the first scanning phase and the highest-ROI finding for an attacker -- it takes minutes to check.
1149
1692
 
1150
1693
  3. **MUST classify every finding with both OWASP category and STRIDE category.** This ensures completeness -- if a finding does not map to either framework, it may be a false positive.
1151
1694
 
@@ -1159,7 +1702,7 @@ These are security review anti-patterns. If you catch yourself doing any of thes
1159
1702
 
1160
1703
  8. **MUST ask the user before making any code changes.** This skill is audit-only by default. Present findings and get explicit approval before touching code.
1161
1704
 
1162
- 9. **MUST consider the full attack surface.** Client-side code, server-side code, CI/CD pipelines, infrastructure configuration, dependency chain, git history -- all of it is in scope.
1705
+ 9. **MUST consider the full attack surface.** Client-side code, server-side code, CI/CD pipelines, infrastructure configuration, dependency chain, git history, LLM integration points, installed skills/agents -- all of it is in scope. The Phase 0.5 census quantifies this surface.
1163
1706
 
1164
1707
  10. **MUST apply the severity bar consistently.** Daily mode (8/10 bar) skips LOW/MEDIUM/INFO. Comprehensive mode (2/10 bar) reports everything. Never mix bars within a single audit.
1165
1708