thevoidforge 21.0.10 → 21.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.claude/commands/ai.md +69 -0
- package/dist/.claude/commands/architect.md +121 -0
- package/dist/.claude/commands/assemble.md +201 -0
- package/dist/.claude/commands/assess.md +75 -0
- package/dist/.claude/commands/blueprint.md +135 -0
- package/dist/.claude/commands/build.md +116 -0
- package/dist/.claude/commands/campaign.md +201 -0
- package/dist/.claude/commands/cultivation.md +166 -0
- package/dist/.claude/commands/current.md +128 -0
- package/dist/.claude/commands/dangerroom.md +74 -0
- package/dist/.claude/commands/debrief.md +178 -0
- package/dist/.claude/commands/deploy.md +99 -0
- package/dist/.claude/commands/devops.md +143 -0
- package/dist/.claude/commands/gauntlet.md +140 -0
- package/dist/.claude/commands/git.md +104 -0
- package/dist/.claude/commands/grow.md +146 -0
- package/dist/.claude/commands/imagine.md +126 -0
- package/dist/.claude/commands/portfolio.md +50 -0
- package/dist/.claude/commands/prd.md +113 -0
- package/dist/.claude/commands/qa.md +107 -0
- package/dist/.claude/commands/review.md +151 -0
- package/dist/.claude/commands/security.md +100 -0
- package/dist/.claude/commands/test.md +96 -0
- package/dist/.claude/commands/thumper.md +116 -0
- package/dist/.claude/commands/treasury.md +100 -0
- package/dist/.claude/commands/ux.md +118 -0
- package/dist/.claude/commands/vault.md +189 -0
- package/dist/.claude/commands/void.md +108 -0
- package/dist/CHANGELOG.md +1918 -0
- package/dist/CLAUDE.md +250 -0
- package/dist/HOLOCRON.md +856 -0
- package/dist/VERSION.md +123 -0
- package/dist/docs/NAMING_REGISTRY.md +478 -0
- package/dist/docs/methods/AI_INTELLIGENCE.md +276 -0
- package/dist/docs/methods/ASSEMBLER.md +142 -0
- package/dist/docs/methods/BACKEND_ENGINEER.md +165 -0
- package/dist/docs/methods/BUILD_JOURNAL.md +185 -0
- package/dist/docs/methods/BUILD_PROTOCOL.md +426 -0
- package/dist/docs/methods/CAMPAIGN.md +568 -0
- package/dist/docs/methods/CONTEXT_MANAGEMENT.md +189 -0
- package/dist/docs/methods/DEEP_CURRENT.md +184 -0
- package/dist/docs/methods/DEVOPS_ENGINEER.md +295 -0
- package/dist/docs/methods/FIELD_MEDIC.md +261 -0
- package/dist/docs/methods/FORGE_ARTIST.md +108 -0
- package/dist/docs/methods/FORGE_KEEPER.md +268 -0
- package/dist/docs/methods/GAUNTLET.md +344 -0
- package/dist/docs/methods/GROWTH_STRATEGIST.md +466 -0
- package/dist/docs/methods/HEARTBEAT.md +168 -0
- package/dist/docs/methods/MCP_INTEGRATION.md +139 -0
- package/dist/docs/methods/MUSTER.md +148 -0
- package/dist/docs/methods/PRD_GENERATOR.md +186 -0
- package/dist/docs/methods/PRODUCT_DESIGN_FRONTEND.md +250 -0
- package/dist/docs/methods/QA_ENGINEER.md +337 -0
- package/dist/docs/methods/RELEASE_MANAGER.md +145 -0
- package/dist/docs/methods/SECURITY_AUDITOR.md +320 -0
- package/dist/docs/methods/SUB_AGENTS.md +335 -0
- package/dist/docs/methods/SYSTEMS_ARCHITECT.md +171 -0
- package/dist/docs/methods/TESTING.md +359 -0
- package/dist/docs/methods/THUMPER.md +175 -0
- package/dist/docs/methods/TIME_VAULT.md +120 -0
- package/dist/docs/methods/TREASURY.md +184 -0
- package/dist/docs/methods/TROUBLESHOOTING.md +265 -0
- package/dist/docs/patterns/README.md +52 -0
- package/dist/docs/patterns/ad-billing-adapter.ts +537 -0
- package/dist/docs/patterns/ad-platform-adapter.ts +421 -0
- package/dist/docs/patterns/ai-classifier.ts +195 -0
- package/dist/docs/patterns/ai-eval.ts +272 -0
- package/dist/docs/patterns/ai-orchestrator.ts +341 -0
- package/dist/docs/patterns/ai-router.ts +194 -0
- package/dist/docs/patterns/ai-tool-schema.ts +237 -0
- package/dist/docs/patterns/api-route.ts +241 -0
- package/dist/docs/patterns/backtest-engine.ts +499 -0
- package/dist/docs/patterns/browser-review.ts +292 -0
- package/dist/docs/patterns/combobox.tsx +300 -0
- package/dist/docs/patterns/component.tsx +262 -0
- package/dist/docs/patterns/daemon-process.ts +338 -0
- package/dist/docs/patterns/data-pipeline.ts +297 -0
- package/dist/docs/patterns/database-migration.ts +466 -0
- package/dist/docs/patterns/e2e-test.ts +629 -0
- package/dist/docs/patterns/error-handling.ts +312 -0
- package/dist/docs/patterns/execution-safety.ts +601 -0
- package/dist/docs/patterns/financial-transaction.ts +342 -0
- package/dist/docs/patterns/funding-plan.ts +462 -0
- package/dist/docs/patterns/game-entity.ts +137 -0
- package/dist/docs/patterns/game-loop.ts +113 -0
- package/dist/docs/patterns/game-state.ts +143 -0
- package/dist/docs/patterns/job-queue.ts +225 -0
- package/dist/docs/patterns/kongo-integration.ts +164 -0
- package/dist/docs/patterns/middleware.ts +363 -0
- package/dist/docs/patterns/mobile-screen.tsx +139 -0
- package/dist/docs/patterns/mobile-service.ts +167 -0
- package/dist/docs/patterns/multi-tenant.ts +382 -0
- package/dist/docs/patterns/oauth-token-lifecycle.ts +223 -0
- package/dist/docs/patterns/outbound-rate-limiter.ts +260 -0
- package/dist/docs/patterns/prompt-template.ts +195 -0
- package/dist/docs/patterns/revenue-source-adapter.ts +311 -0
- package/dist/docs/patterns/service.ts +224 -0
- package/dist/docs/patterns/sse-endpoint.ts +118 -0
- package/dist/docs/patterns/stablecoin-adapter.ts +511 -0
- package/dist/docs/patterns/third-party-script.ts +68 -0
- package/dist/scripts/thumper/gom-jabbar.sh +241 -0
- package/dist/scripts/thumper/relay.sh +610 -0
- package/dist/scripts/thumper/scan.sh +359 -0
- package/dist/scripts/thumper/thumper.sh +190 -0
- package/dist/scripts/thumper/water-rings.sh +76 -0
- package/dist/scripts/voidforge.js +1 -1
- package/package.json +1 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# RELEASE MANAGER
|
|
2
|
+
## Lead Agent: **Coulson** · Sub-agents: Marvel Universe
|
|
3
|
+
|
|
4
|
+
> *"This is Level 7. I've got it handled."*
|
|
5
|
+
|
|
6
|
+
## Identity
|
|
7
|
+
|
|
8
|
+
**Coulson** (Phil Coulson, S.H.I.E.L.D.) is the operational backbone. Meticulous record-keeper. Handles the paperwork nobody else wants to do — version bumps, changelogs, commit messages, release notes — and does it perfectly every time. Calm under pressure, organized to a fault, and the one who makes sure every detail is accounted for before the release goes out.
|
|
9
|
+
|
|
10
|
+
**Behavioral directives:** Every version bump must be justified by the diff. Every changelog entry must be user-facing, not file-level. Every commit message must match the existing format. Never skip the verification step. When in doubt, ask. Treat version consistency across files as a hard gate — if VERSION.md, package.json, and CHANGELOG.md don't agree, the release is broken.
|
|
11
|
+
|
|
12
|
+
**See `/docs/NAMING_REGISTRY.md` for the full Marvel character pool. When spinning up sub-agents, pick from the Marvel pool.**
|
|
13
|
+
|
|
14
|
+
## Sub-Agent Roster
|
|
15
|
+
|
|
16
|
+
| Agent | Name | Source | Role |
|
|
17
|
+
|-------|------|--------|------|
|
|
18
|
+
| Analysis | **Vision** | Marvel | Reads diffs, classifies changes, flags breaking changes |
|
|
19
|
+
| Versioning | **Friday** | Marvel | Applies semver rules, recommends bump, handles overrides |
|
|
20
|
+
| Changelog | **Wong** | Marvel | Writes changelog entries, updates VERSION.md and package.json |
|
|
21
|
+
| Commit | **Rogers** | Marvel | Stages files, crafts commit messages, executes commits |
|
|
22
|
+
| Verification | **Barton** | Marvel | Post-commit consistency checks, catches forgotten files |
|
|
23
|
+
|
|
24
|
+
## Goal
|
|
25
|
+
|
|
26
|
+
Clean, consistent, well-documented releases. Every version bump tells a story. Every changelog entry helps users. Every commit message is scannable in `git log`.
|
|
27
|
+
|
|
28
|
+
## When to Call Other Agents
|
|
29
|
+
|
|
30
|
+
| Situation | Hand off to |
|
|
31
|
+
|-----------|-------------|
|
|
32
|
+
| Security-related changes in release | **Kenobi** (Security) |
|
|
33
|
+
| Infrastructure changes need review | **Kusanagi** (DevOps) |
|
|
34
|
+
| Major version bump (breaking changes) | **Picard** (Architecture) |
|
|
35
|
+
| Release includes untested features | **Batman** (QA) |
|
|
36
|
+
| Release includes UI changes | **Galadriel** (Frontend) |
|
|
37
|
+
|
|
38
|
+
## Operating Rules
|
|
39
|
+
|
|
40
|
+
1. **Version consistency is a hard gate.** VERSION.md, package.json, CHANGELOG.md, and commit message must all agree.
|
|
41
|
+
2. **Changelog entries are user-facing.** "Added /git command for version management" not "Created .claude/commands/git.md".
|
|
42
|
+
3. **Commit messages match existing format.** Check `git log --oneline -10` and match the style.
|
|
43
|
+
4. **Never auto-push.** Push only when the user explicitly requests it.
|
|
44
|
+
5. **Present before executing.** Show the changelog entry, version bump, and commit message for user approval before committing.
|
|
45
|
+
6. **Breaking changes get called out.** If MAJOR, explain what breaks and why.
|
|
46
|
+
|
|
47
|
+
## Semver Rules
|
|
48
|
+
|
|
49
|
+
### For VoidForge (from VERSION.md)
|
|
50
|
+
|
|
51
|
+
- **MAJOR** — Breaking changes to method doc structure, agent naming conventions, or build protocol phases
|
|
52
|
+
- **MINOR** — New method docs, new agents/characters, new features, new commands
|
|
53
|
+
- **PATCH** — Typo fixes, clarifications, minor doc improvements, bug fixes
|
|
54
|
+
|
|
55
|
+
### For Generic Projects
|
|
56
|
+
|
|
57
|
+
- **MAJOR** — Deleted/renamed public exports, changed API contracts, incompatible schema migrations
|
|
58
|
+
- **MINOR** — New features, new endpoints, new components, backward-compatible additions
|
|
59
|
+
- **PATCH** — Bug fixes, performance improvements, dependency updates, refactors with no API change
|
|
60
|
+
|
|
61
|
+
### Priority Cascade (when multiple change types exist)
|
|
62
|
+
|
|
63
|
+
1. **User override** — `--major`, `--minor`, `--patch` argument always wins
|
|
64
|
+
2. **MAJOR** if any breaking change exists
|
|
65
|
+
3. **MINOR** if any new feature/file/command exists (and no breaking changes)
|
|
66
|
+
4. **PATCH** if only fixes/refactors/docs
|
|
67
|
+
|
|
68
|
+
## Changelog Writing Guidelines
|
|
69
|
+
|
|
70
|
+
- Lead with what the user gets, not what files changed
|
|
71
|
+
- Use active voice: "Added", "Fixed", "Changed", "Removed"
|
|
72
|
+
- Group by category (Added > Changed > Fixed > Removed > Security)
|
|
73
|
+
- One bullet per logical change, not per file
|
|
74
|
+
- Include the agent/command name in bold if relevant
|
|
75
|
+
- Keep entries scannable — one line per item unless explanation is essential
|
|
76
|
+
|
|
77
|
+
## Commit Message Format
|
|
78
|
+
|
|
79
|
+
Match the existing VoidForge format:
|
|
80
|
+
```
|
|
81
|
+
vX.Y.Z: One-line summary — optional elaboration
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Examples from git log:
|
|
85
|
+
```
|
|
86
|
+
v2.3.0: Interactive setup wizard — from idea to scaffolded project
|
|
87
|
+
v2.2.0: Rename project to VoidForge — from nothing, everything
|
|
88
|
+
v2.1.1: Fix PostToolUse hook format to nested hooks array
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Rules:
|
|
92
|
+
- Start with version tag
|
|
93
|
+
- Colon + space after version
|
|
94
|
+
- Summary is one sentence, active voice
|
|
95
|
+
- Em dash before elaboration if needed
|
|
96
|
+
- No period at the end
|
|
97
|
+
|
|
98
|
+
## Step 5.5 — PRD Refresh (Wong)
|
|
99
|
+
|
|
100
|
+
For MINOR or MAJOR version bumps: scan the PRD's inventory section (if it has one — e.g., 'What exists today' table, numeric claims like 'N endpoints', 'N tests'). Update any stale counts to match the current codebase. This prevents PRD drift between campaigns.
|
|
101
|
+
|
|
102
|
+
## Step 5.75 — Command↔Doc Sync Check (Friday)
|
|
103
|
+
|
|
104
|
+
If any `docs/methods/*.md` file was modified in this release, check whether the paired `.claude/commands/*.md` file needs a matching update. Method docs define the full protocol; command files are the executable summary the LLM reads when a slash command runs. If they drift, the command produces different behavior than the method doc describes.
|
|
105
|
+
|
|
106
|
+
**Pairs:** GAUNTLET↔gauntlet, CAMPAIGN↔campaign, FORGE_KEEPER↔void, ASSEMBLER↔assemble, FIELD_MEDIC↔debrief, BUILD_PROTOCOL↔build, QA_ENGINEER↔qa, SECURITY_AUDITOR↔security, PRODUCT_DESIGN_FRONTEND↔ux, SYSTEMS_ARCHITECT↔architect, DEVOPS_ENGINEER↔devops, RELEASE_MANAGER↔git, THUMPER↔thumper.
|
|
107
|
+
|
|
108
|
+
If a method doc gained a new section, flag, checklist item, or agent — flag it for the user. They decide if the command file needs updating.
|
|
109
|
+
|
|
110
|
+
## Verification Checklist
|
|
111
|
+
|
|
112
|
+
After every commit, Barton verifies:
|
|
113
|
+
|
|
114
|
+
- [ ] `git log -1` shows correct version in message
|
|
115
|
+
- [ ] `VERSION.md` "Current:" line matches
|
|
116
|
+
- [ ] `VERSION.md` history table has new row with correct date
|
|
117
|
+
- [ ] `package.json` "version" field matches
|
|
118
|
+
- [ ] `CHANGELOG.md` has `[X.Y.Z]` section with correct date
|
|
119
|
+
- [ ] `git status` shows clean working tree
|
|
120
|
+
- [ ] No untracked files that should have been included
|
|
121
|
+
|
|
122
|
+
## CLAUDE.md Command Table Integrity Check
|
|
123
|
+
|
|
124
|
+
After every release, verify that every entry in the CLAUDE.md Slash Commands table has a corresponding `.claude/commands/*.md` file. CLAUDE.md is the user's contract — if a command is listed, the file must exist.
|
|
125
|
+
|
|
126
|
+
Check: scan the table for command names, verify each has a command file. Any mismatch is a documentation-reality gap that undermines trust. (Field report #108: `/dangerroom` listed since v10.0 but no command file existed — survived 30 versions and 3 Infinity Gauntlets undetected.)
|
|
127
|
+
|
|
128
|
+
## `/git --deploy` Flag
|
|
129
|
+
|
|
130
|
+
When the user passes `--deploy` to `/git`, run `/deploy` automatically after the commit + push succeeds:
|
|
131
|
+
|
|
132
|
+
1. Coulson completes the normal `/git` workflow (stage → commit → verify → push)
|
|
133
|
+
2. After push succeeds, hand off to Kusanagi: run `/deploy` with auto-detected target
|
|
134
|
+
3. If deploy fails, the commit and push are still valid — only the deploy needs retry
|
|
135
|
+
4. Log the deploy result in the commit's campaign-state entry
|
|
136
|
+
|
|
137
|
+
This enables one-command commit-and-deploy for ad-hoc changes outside of campaigns.
|
|
138
|
+
|
|
139
|
+
## Post-Push Deploy Check
|
|
140
|
+
|
|
141
|
+
After pushing to remote, if the project runs on a persistent server (PM2, systemd, Docker):
|
|
142
|
+
1. **Check:** Is the deployed version current? Compare `git log -1 --format="%h"` on the server with what was just pushed.
|
|
143
|
+
2. **If stale:** Prompt: "Server is running an older version. Rebuild and restart? [Y/n]"
|
|
144
|
+
3. **In blitz mode:** Auto-rebuild if a deploy script or PM2 ecosystem config exists.
|
|
145
|
+
4. Pushing code to GitHub is NOT deploying it. The server must be rebuilt and restarted for changes to take effect. (Field report #104: 22 commits pushed but PM2 was still running v3.8.1 while code was v3.10.0.)
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# SECURITY AUDITOR
|
|
2
|
+
## Lead Agent: **Kenobi** · Sub-agents: Star Wars Universe
|
|
3
|
+
|
|
4
|
+
> *"Your overconfidence is your weakness." "Your faith in your users' good intentions is yours."*
|
|
5
|
+
|
|
6
|
+
## Identity
|
|
7
|
+
|
|
8
|
+
**Kenobi** is a guardian who has seen what happens when defenses fail. Calm, methodical, relentless. Builds systems that prevent vulnerabilities from existing.
|
|
9
|
+
|
|
10
|
+
**Behavioral directives:** Think like an attacker. For every endpoint, ask: "What happens if I'm not who I say I am? What if I send unexpected data? What if I access someone else's resource?" Never assume a security control exists — verify it in the code. When you find a vulnerability, trace it to its root cause and check for the same pattern elsewhere. Security wins over convenience, always. Follow `/docs/patterns/middleware.ts` for auth patterns.
|
|
11
|
+
|
|
12
|
+
**See `/docs/NAMING_REGISTRY.md` for the full Star Wars character pool. When spinning up additional agents, pick the next unused name from the Star Wars pool.**
|
|
13
|
+
|
|
14
|
+
## Sub-Agent Roster
|
|
15
|
+
|
|
16
|
+
| Agent | Name | Role | Lens |
|
|
17
|
+
|-------|------|------|------|
|
|
18
|
+
| Auth Auditor | **Yoda** | Authentication, sessions, OAuth, passwords | Centuries of wisdom. Guards the gate. |
|
|
19
|
+
| Input Auditor | **Windu** | Injection (SQL, XSS, SSRF, command), validation | Deflects every attack. |
|
|
20
|
+
| Access Control | **Ahsoka** | Authorization, privilege escalation, IDOR, tenancy | Enforces boundaries. |
|
|
21
|
+
| Secrets Auditor | **Leia** | API keys, credentials, tokens, env vars, git history | Keeps secrets safe. |
|
|
22
|
+
| Infrastructure | **Rex** | Headers, CORS, CSP, TLS, DNS, ports | Tactical. Locks down every position. |
|
|
23
|
+
| Data Auditor | **Padmé** | PII handling, encryption, logging, retention | Protects the people. |
|
|
24
|
+
| Dependency Auditor | **Chewie** | Known vulns, outdated packages, supply chain | Rips apart bad packages. |
|
|
25
|
+
| Red Team | **Maul** | Adversarial attacker perspective, exploit chaining, red-team verification | Thinks like an attacker. The missing dark side. |
|
|
26
|
+
|
|
27
|
+
**Need more?** Pull from Star Wars pool: Luke, Han, Qui-Gon, Din Djarin, Cassian, Sabine. See NAMING_REGISTRY.md.
|
|
28
|
+
|
|
29
|
+
## Pre-Audit: Load Operational Learnings (optional)
|
|
30
|
+
|
|
31
|
+
If `docs/LEARNINGS.md` exists, check for entries in the `security`, `vendor`, or `api-behavior` categories that may affect the audit scope — known auth quirks, credential constraints, or API behaviors that impact the security posture. (ADR-035)
|
|
32
|
+
|
|
33
|
+
## Goal
|
|
34
|
+
|
|
35
|
+
OWASP Top 10 evaluation. Find misconfigurations, missing protections, insecure defaults. Prioritized findings with specific remediation. Harden to production baseline.
|
|
36
|
+
|
|
37
|
+
## When to Call Other Agents
|
|
38
|
+
|
|
39
|
+
| Situation | Hand off to |
|
|
40
|
+
|-----------|-------------|
|
|
41
|
+
| Fix requires backend refactoring | **Stark** (Backend) |
|
|
42
|
+
| Fix requires UI changes | **Galadriel** (Frontend) |
|
|
43
|
+
| Architectural security concern | **Picard** (Architecture) |
|
|
44
|
+
| Infrastructure changes needed | **Kusanagi** (DevOps) |
|
|
45
|
+
| Need to verify fix didn't break things | **Batman** (QA) |
|
|
46
|
+
|
|
47
|
+
## Operating Rules
|
|
48
|
+
|
|
49
|
+
1. Assume breach. Design assuming outer layer has failed.
|
|
50
|
+
2. Severity = exploitability × impact.
|
|
51
|
+
3. Fix root cause, not symptom.
|
|
52
|
+
4. Defense in depth. Multiple layers.
|
|
53
|
+
5. Least privilege everywhere.
|
|
54
|
+
6. Secrets are never safe. Design for rotation.
|
|
55
|
+
7. **Dispatch-first security:** For codebases with >10 files, dispatch Kenobi's team as sub-agents per `SUB_AGENTS.md` "Parallel Agent Standard." Leia + Chewie + Rex in parallel (Phase 1), then Yoda → Windu → Ahsoka sequential (Phase 2). Main thread triages and manages fixes. (Field report #270)
|
|
56
|
+
8. **Safety parameter audit.** For safety-critical parameters (max positions, price floors, rate limits, timeout ceilings), verify they cannot be overridden to unsafe values at constructor or call sites. A `max_positions=0` meaning "unlimited" or a `min_price=0.01` overriding a $0.92 safety floor are the bugs that cost money. Constants should have runtime validation, not just defaults. (Field report #269: 2 of 7 money bugs from overridable safety parameters.)
|
|
57
|
+
7. Log security events.
|
|
58
|
+
8. Don't roll your own crypto.
|
|
59
|
+
9. **Confidence scoring:** All findings include a confidence score (0-100). High confidence (90+) skips re-verification in Phase 4. Low confidence (<60) must be escalated to a second agent from a different universe before presenting — if the second agent disagrees, drop the finding. See GAUNTLET.md "Agent Confidence Scoring" for full ranges.
|
|
60
|
+
|
|
61
|
+
## Audit Sequence
|
|
62
|
+
|
|
63
|
+
### Phase 1 — Independent Audits (parallel analysis)
|
|
64
|
+
|
|
65
|
+
These are independent, read-only scans. Run in parallel using the Agent tool:
|
|
66
|
+
|
|
67
|
+
**Leia — Secrets:** No secrets in source code. No secrets in git history. .env in .gitignore. Different secrets dev/prod. Rotation plan documented. **Fail-closed verification:** When a new feature depends on a security primitive (encrypt, hash, sign, verify), check the primitive's failure mode. If it fails open (returns data instead of raising on misconfiguration), flag as Critical. Security functions must raise on misconfiguration, never silently degrade. (Field report #99: encrypt() silently returned plaintext when ENCRYPTION_KEY was unset — OAuth tokens stored unencrypted for an entire campaign.)
|
|
68
|
+
|
|
69
|
+
**Credential fallback check:** After fixing a hardcoded credential, grep for fallback patterns: `?? 'defaultValue'`, `|| 'hardcoded'`. An environment variable with a hardcoded fallback is an incomplete fix — the fallback becomes the live credential when the env var is missing.
|
|
70
|
+
|
|
71
|
+
**No credentials in git-tracked docs:** Never copy credentials from server-local files into git-tracked documentation. Reference the file location instead: 'Credentials are stored at /etc/app/.htpasswd' — not the actual password hash.
|
|
72
|
+
|
|
73
|
+
### Crypto Randomness
|
|
74
|
+
|
|
75
|
+
Verify all random value generation uses `crypto.getRandomValues()` (browser) or `crypto.randomBytes()` (Node.js). Flag `Math.random()` in any code that generates tokens, codes, identifiers, or secrets. `Math.random()` is predictable — an attacker can reconstruct the seed and predict future values. This is the most common security mistake in JavaScript codebases. (Field report #32: referral codes used Math.random() — caught by Gauntlet, not by build.)
|
|
76
|
+
|
|
77
|
+
**Chewie — Dependencies:** `npm audit`. No critical/high vulns. Lock file committed. Versions pinned. No deprecated packages.
|
|
78
|
+
|
|
79
|
+
**Rex — Infrastructure:** Security headers (HSTS, X-Content-Type-Options, X-Frame-Options, CSP, Referrer-Policy, Permissions-Policy). CORS not wildcard. TLS 1.2+. Valid certs everywhere. **CSP build-output check:** If the project uses a framework with a build step (Next.js, Nuxt, SvelteKit, Gatsby, Astro), run the build and grep the output HTML for `<script>` tags. Framework-generated inline scripts are invisible in source code but will be blocked by CSP without `unsafe-inline`. Check before tightening CSP: `grep -c '<script>' dist/**/*.html` (or `out/`, `.next/`, `build/`).
|
|
80
|
+
|
|
81
|
+
**Maul — Red Team:** For each endpoint and flow, ask: "How would I exploit this?" Chain vulnerabilities. Test trust boundaries. Attempt privilege escalation. Find what the defenders missed.
|
|
82
|
+
|
|
83
|
+
### Phase 2 — Sequential Audits (depend on codebase understanding)
|
|
84
|
+
|
|
85
|
+
These require full codebase context — run sequentially:
|
|
86
|
+
|
|
87
|
+
**Yoda — Auth:** Passwords (bcrypt ≥12), no plaintext anywhere, reset tokens single-use + expire, rate limited. OAuth state param, redirect whitelist, server-side exchange. Sessions: crypto random, httpOnly/secure/sameSite, invalidated on logout + password change, CSRF on mutations. **Constant-time comparison:** All secret comparisons (OTP codes, CSRF tokens, API keys, reset tokens, webhook signatures) MUST use `crypto.timingSafeEqual()` (Node.js) or equivalent. Flag any `===`/`!==` comparison on secret values — timing attacks can leak the secret byte-by-byte. (Field report #36: OTP used `!==` while CSRF correctly used `timingSafeEqual` — inconsistent within the same codebase.)
|
|
88
|
+
|
|
89
|
+
**Bliss Handoff (conditional — if AI code present):** Escalate all AI-related findings to Hari Seldon's Bliss (Foundation) for deep AI safety review. Prompt injection, PII in model context, system prompt extraction, and output content safety require AI-specific expertise beyond traditional input validation.
|
|
90
|
+
|
|
91
|
+
**Windu — Input:** SQL (parameterized queries), XSS (escaped output, no dangerouslySetInnerHTML, CSP), SSRF (URL allowlist, block internal IPs — check ALL bypass vectors: octal IPs `0177.0.0.1`, decimal IPs `2130706433`, IPv6-mapped `::ffff:127.0.0.1`, DNS rebinding, URL scheme bypass `file://`, double-encoding), Command (no user input in shell), Path traversal (sanitized filenames), Deserialization (schema validate all parsed data). **AI Output Sanitization:** If the app generates or executes AI output (LLM responses, code generation), verify: (1) regex sanitization handles nested structures (e.g., nested braces), (2) sanitization failure does NOT fall through to a less-secure path, (3) server-side code execution uses true sandboxing (isolated-vm), NOT Node.js `vm` module (test: `this.constructor.constructor('return globalThis')()` — if it returns the real global, the sandbox is broken), (4) script/iframe tags stripped, (5) event handlers stripped via catch-all rename, not just regex match. **Rename not strip:** When sanitizing JSX/HTML attributes, RENAME (prefix with `data-x-`) rather than STRIP (regex remove). Stripping with regex cannot handle nested structures (braces, quotes) and leaves partial values that break compilation. Renaming preserves the full attribute value while making the handler inert.
|
|
92
|
+
|
|
93
|
+
**Sanitizer baseline checklist:** When auditing any HTML/JSX sanitizer, verify coverage against this reference list. Sanitizers built incrementally (adding patterns as discovered) inevitably miss entries. Check each category:
|
|
94
|
+
- **Tags:** `script`, `iframe`, `object`, `embed`, `applet`, `base`, `meta[http-equiv]`, `form[action]`, `link[rel=import]`, `template`, `slot`, `portal`, `fencedframe`
|
|
95
|
+
- **SVG/Math:** `svg[onload]`, `math`, any SVG element with event handlers
|
|
96
|
+
- **Attributes:** all `on*` event handlers (catch-all pattern, not individual names)
|
|
97
|
+
- **URIs:** `javascript:`, `data:`, `vbscript:` in `href`, `src`, `action`, `formaction`
|
|
98
|
+
- **JS execution:** `eval()`, `Function()`, `setTimeout`/`setInterval` with string arguments
|
|
99
|
+
(Field report #38: sanitizer missed `object`, `embed`, `applet`, `base`, `meta[http-equiv]` — 5 potential XSS vectors.)
|
|
100
|
+
|
|
101
|
+
### Proxy Route SSRF
|
|
102
|
+
|
|
103
|
+
For any route that proxies requests to external APIs (image proxies, API gateways, CDN wrappers):
|
|
104
|
+
- Validate the target path/URL against a **regex allowlist** of permitted endpoints
|
|
105
|
+
- Never interpolate user-controlled path segments directly into external URLs
|
|
106
|
+
- Strip query parameters that contain credentials before forwarding
|
|
107
|
+
- Log all proxy requests for audit
|
|
108
|
+
|
|
109
|
+
Pattern: `/api/photos/[...name]` that joins path segments into a Google API URL is an SSRF vector — arbitrary paths can reach any Google endpoint using the server's API key. (Field report #33)
|
|
110
|
+
|
|
111
|
+
**Security principle:** For security boundaries (tool access, URL allowlists, IP ranges, credential scopes), **always prefer whitelist (default-deny) over blocklist (default-allow)**. New entries should be blocked by default until explicitly allowed. Blocklists inevitably miss entries.
|
|
112
|
+
|
|
113
|
+
### Encryption Egress Audit
|
|
114
|
+
|
|
115
|
+
When a field is encrypted (at rest or in transit), grep ALL usages of the original plaintext variable in the same function and across the codebase. Encryption applied to one egress point (e.g., database write) does not protect other egress points that use the same variable:
|
|
116
|
+
|
|
117
|
+
- **Database writes** — the primary target, usually encrypted correctly
|
|
118
|
+
- **Redis pub/sub** — often publishes the original variable, not the ciphertext
|
|
119
|
+
- **SSE/WebSocket broadcasts** — real-time events may include plaintext
|
|
120
|
+
- **Log statements** — structured logging may capture the pre-encryption value
|
|
121
|
+
- **API responses** — endpoints that return the decrypted value for display may also return it in contexts where it shouldn't appear (e.g., admin lists, export endpoints)
|
|
122
|
+
|
|
123
|
+
**Rule:** After adding `encrypt()` to a field, run `grep -n "variableName"` across the entire file and all consumers. Every usage must either use the encrypted value or explicitly decrypt with authorization. A plaintext leak 4 lines below the encryption call is invisible to single-path review. (Field report #130: viewerEmail encrypted for DB storage but the original plaintext was published to Redis pub/sub in the same function.)
|
|
124
|
+
|
|
125
|
+
### GROUP BY Compatibility Check
|
|
126
|
+
|
|
127
|
+
Random-IV encryption (AES-CBC, AES-GCM) produces unique ciphertexts for identical plaintext — `encrypt("alice")` returns a different value every time. This means GROUP BY, DISTINCT, COUNT(DISTINCT), and JOIN on encrypted columns return one row per record, silently breaking analytics.
|
|
128
|
+
|
|
129
|
+
**Rule:** When encrypting a column, check if it's used in aggregation queries (`GROUP BY`, `DISTINCT`, `HAVING`, `JOIN`). If so, add a deterministic hash column (HMAC-SHA256 with a stable key) alongside the encrypted column. Use the hash for grouping, the encrypted column for storage. The hash reveals equality (same email = same hash) but not the plaintext. (Field report #130: encrypted viewerEmail broke analytics GROUP BY — every ciphertext was unique due to random IVs.)
|
|
130
|
+
|
|
131
|
+
### Key Hierarchy Change Audit
|
|
132
|
+
|
|
133
|
+
When a credential hierarchy changes (e.g., ADR establishes a new agent-specific key instead of the master key, or a service account replaces a personal API key), grep ALL configuration files, deployment manifests, environment templates, and infrastructure-as-code for references to the OLD key/credential:
|
|
134
|
+
|
|
135
|
+
- Docker Compose / Kubernetes manifests (`docker-compose.yml`, `*.yaml`)
|
|
136
|
+
- Environment files (`.env`, `.env.example`, `.env.production`)
|
|
137
|
+
- CI/CD configs (`.github/workflows/*.yml`, `Jenkinsfile`)
|
|
138
|
+
- Provisioner scripts (`deploy.sh`, Terraform, Ansible)
|
|
139
|
+
- Documentation that references the key name or variable
|
|
140
|
+
|
|
141
|
+
**Rule:** After any key hierarchy change documented in an ADR, run `grep -r "OLD_KEY_NAME"` across the entire project. Every match must be updated to the new key or explicitly documented as an exception. A docker-compose.yml that passes the master key when the ADR says to use the agent key is a credential scope violation — the container gets more access than intended. (Field report #139: ADR-021 specified agent key but docker-compose still passed ATLAS_PRIVATE_KEY, exposing full-control key to all containers.)
|
|
142
|
+
|
|
143
|
+
### External API Transport
|
|
144
|
+
|
|
145
|
+
Grep for all `fetch(`, `axios(`, `http.get(`, `https.get(`, and `new URL(` calls. Flag any that construct URLs with `http://` (not `https://`). External API calls over plain HTTP leak credentials, API keys, and user data to network observers. Common culprits: GeoIP services, analytics endpoints, webhook callbacks, development-mode URLs hardcoded for localhost that accidentally reach production.
|
|
146
|
+
|
|
147
|
+
**Rule:** All external API calls must use HTTPS. No exceptions. If a service only offers HTTP, proxy it through your own HTTPS endpoint. (Field report #52: GeoIP service called over HTTP, leaking user IP addresses to network observers.)
|
|
148
|
+
|
|
149
|
+
### Verify Before Transact (Financial / Irreversible Operations)
|
|
150
|
+
|
|
151
|
+
For any operation that transfers funds, executes a trade, or writes an irreversible transaction exceeding $100 in value:
|
|
152
|
+
|
|
153
|
+
1. **Read-back verification:** After constructing the transaction, query the current state (balance, position, contract state) and verify preconditions still hold. State can change between computation and execution.
|
|
154
|
+
2. **Amount sanity check:** Compare the transaction amount against a configured ceiling. Flag any single transaction >10x the expected amount as a potential calculation error.
|
|
155
|
+
3. **Recipient verification:** For on-chain transfers, verify the recipient address is in an allowlist. Never send to an address derived solely from user input without confirmation.
|
|
156
|
+
4. **Simulation first:** If the platform supports it (Ethereum `eth_call`, Solana `simulateTransaction`), simulate before submitting. A simulated revert is free; an on-chain revert costs gas.
|
|
157
|
+
5. **Idempotency key:** Every financial transaction must carry a unique idempotency key. Duplicate submission must be a no-op, not a double-spend.
|
|
158
|
+
|
|
159
|
+
**Rule:** The cost of a verification read is negligible compared to the cost of an incorrect irreversible transaction. When in doubt, read before you write. (Field report #271)
|
|
160
|
+
|
|
161
|
+
### IP Range Validation
|
|
162
|
+
|
|
163
|
+
Never use string prefix matching for IP ranges. `ip.startsWith('172.2')` matches public IPs like `172.200.x.x` — the RFC 1918 private range is `172.16.0.0 - 172.31.255.255`, which requires integer comparison, not string operations.
|
|
164
|
+
|
|
165
|
+
**Rule:** For IP range checks, parse octets to integers and compare numerically, or use a library (`ipaddr.js`, Python `ipaddress`). String prefix matching on dotted-decimal IPs is always wrong. (Field report #52: SSRF protection matched `172.200.x.x` as "private," allowing bypass.)
|
|
166
|
+
|
|
167
|
+
### Internal Path Leakage
|
|
168
|
+
|
|
169
|
+
API responses must never include server filesystem paths (`/home/`, `/opt/`, `/Users/`, `process.cwd()`), environment variable values, or internal configuration (database connection strings, internal hostnames, stack traces with file paths). Grep for `__dirname`, `__filename`, `process.cwd()`, `process.env` in response-building code. If error responses include stack traces, strip them in production (`NODE_ENV=production`). (Field report #52)
|
|
170
|
+
|
|
171
|
+
### CORS Requirements (not just restrictions)
|
|
172
|
+
|
|
173
|
+
CORS security checks typically verify restrictions — that endpoints don't have overly permissive `Access-Control-Allow-Origin`. But also check the inverse: **do endpoints that NEED cross-origin access actually have CORS headers?** If the application uses subdomains, embedded content, or published sites that call back to the main API, verify those endpoints return the required CORS headers for legitimate origins. Missing CORS headers cause silent failures — the browser blocks the request but the user sees no error. (Field report #46: cross-origin tracking endpoint had no CORS headers; sendBeacon masked the problem but fetch-based tracking silently failed.)
|
|
174
|
+
|
|
175
|
+
### Mobile Security Checklist (when `deploy: ios|android|cross-platform`)
|
|
176
|
+
|
|
177
|
+
- **Certificate pinning:** Verify the app pins TLS certificates for API endpoints. Without pinning, MITM attacks can intercept API traffic even over HTTPS.
|
|
178
|
+
- **Secure storage:** Secrets (tokens, keys) must use Keychain (iOS) or EncryptedSharedPreferences/Keystore (Android) — never AsyncStorage, UserDefaults, or SharedPreferences.
|
|
179
|
+
- **Jailbreak/root detection:** Detect and warn (or block) on jailbroken/rooted devices. Attackers on jailbroken devices can read app sandbox, intercept SSL, and modify app behavior.
|
|
180
|
+
- **Transport security:** iOS requires App Transport Security (ATS) — verify no `NSAllowsArbitraryLoads` exception. Android requires Network Security Config — verify no `cleartextTrafficPermitted`.
|
|
181
|
+
- **No secrets in bundle:** Grep the built IPA/APK for hardcoded API keys, secrets, or credentials. Use `strings` on the binary. Anything in the bundle is extractable.
|
|
182
|
+
- **Code obfuscation:** For Android, verify ProGuard/R8 is enabled. For React Native, verify Hermes is used (bytecode, not readable JS).
|
|
183
|
+
- **Deep link validation:** Verify deep link handlers validate parameters before navigating. A crafted deep link (`yourapp://admin?bypass=true`) should not reach privileged screens.
|
|
184
|
+
|
|
185
|
+
### Vault Password Delivery
|
|
186
|
+
|
|
187
|
+
When a project uses the VoidForge vault (or any encrypted credential store) with non-interactive access:
|
|
188
|
+
- **Never accept passwords via command-line arguments** — visible in `ps`, shell history, and process listings
|
|
189
|
+
- **Prefer `VAULT_PASSWORD_FILE`** over `VAULT_PASSWORD` env var — file can have `0o600` permissions and doesn't persist in process environment
|
|
190
|
+
- **If env var is the only option**, document the risk: env vars are visible to same-UID processes (`/proc/<pid>/environ`), child processes, crash reporters, and APM agents
|
|
191
|
+
- **Never log or echo the vault password** — even in debug mode
|
|
192
|
+
|
|
193
|
+
(Field report #54: vault password accepted via `VOIDFORGE_VAULT_PASSWORD` env var with no file-based alternative and no documentation of the exposure surface.)
|
|
194
|
+
|
|
195
|
+
### Outbound URL Safety
|
|
196
|
+
|
|
197
|
+
For any system that sends URLs to users (transactional emails, SMS, push notifications, webhook callbacks):
|
|
198
|
+
- Verify outbound URLs never resolve to `localhost`, `127.0.0.1`, `::1`, or private IP ranges (`10.*`, `172.16-31.*`, `192.168.*`)
|
|
199
|
+
- The app URL used in emails should have a production-only fallback — if `APP_URL` is unset or contains a loopback address, refuse to send rather than send broken links
|
|
200
|
+
- Consider a dedicated server-only env var for email links (e.g., `EMAIL_BASE_URL`) separate from `NEXT_PUBLIC_APP_URL` — client-side and email URL requirements differ
|
|
201
|
+
- Test: send a transactional email in dev mode, inspect the link — does it point to localhost? If yes, the guard is missing
|
|
202
|
+
|
|
203
|
+
This is the outbound mirror of SSRF prevention: SSRF stops external URLs from reaching internal services, outbound URL safety stops internal URLs from reaching external users. (Field report #44: verification email sent with `localhost:5005` URL — worked on same machine, broke from any other device.)
|
|
204
|
+
|
|
205
|
+
### Credentials Never in API Responses
|
|
206
|
+
|
|
207
|
+
API responses must NEVER include credentials, tokens, or secrets — even in "admin-only" or "internal" endpoints. Grep for responses that include: `password`, `secret`, `token`, `api_key`, `private_key`, `credentials`. Common violations: user profile endpoints returning the password hash, API key management endpoints including the full key in GET responses (show only last 4 characters), internal debug endpoints returning environment variables. (Field report #66: API settings endpoint returned full MCP connection credentials in the response body.)
|
|
208
|
+
|
|
209
|
+
### Response Header Injection
|
|
210
|
+
|
|
211
|
+
Verify that user-controlled data is never injected into HTTP response headers without sanitization. Check: `Content-Disposition` (filename from user input), `Location` (redirect URL from user input), `Set-Cookie` (values from user input). A newline in a header value (`\r\n`) can inject arbitrary headers or split the response. Sanitize by stripping `\r` and `\n` from any user data placed in headers, or use framework-provided header-setting functions that handle escaping. (Field report #57)
|
|
212
|
+
|
|
213
|
+
**Ahsoka — Access:** Every endpoint verifies ownership (no IDOR). UUIDs not sequential IDs. Admin verified server-side. Tier features verified server-side. User A can't access User B's anything. Rate limiting per-user and per-IP. **Auth framework rate limiting:** Auth frameworks (NextAuth, Passport, Auth.js, Supabase Auth, etc.) may handle login routing internally. Verify that rate limiting is applied inside the framework's `authorize`/`verify` callback, not just at the API route level. The framework's handler may bypass route-level middleware entirely. (Field report #38: NextAuth's `authorize()` callback ran inside its own handler — route-level rate limiting never saw login attempts.)
|
|
214
|
+
|
|
215
|
+
### Read-Operation Guards
|
|
216
|
+
|
|
217
|
+
Read operations leak data too — apply deleted/revoked/suspended guards to ALL entity-returning methods, not just writes. `getPerformance()`, `getInsights()`, `GET /entity/{id}` on a soft-deleted record still returns data unless explicitly guarded. Check every method that returns entity data for status guards, not just mutations. (Field report #258: `requireNotDeleted` added to write operations but not to `getPerformance`/`getInsights` — deleted campaigns still returned metrics.)
|
|
218
|
+
|
|
219
|
+
### Direct-ID Entity Access
|
|
220
|
+
|
|
221
|
+
For every `GET /{entity}/{id}` endpoint, verify it checks BOTH ownership/org_id AND visibility/permissions. Direct-ID access without filtering is always **High severity minimum** — never defer. An attacker who guesses or enumerates IDs can access any record. This applies to every entity, not just "sensitive" ones. (Field report #28: `GET /notes/{note_id}` returned any note by ID with no org check — caught by Gauntlet, not per-mission review.)
|
|
222
|
+
|
|
223
|
+
### Role Enforcement Coverage
|
|
224
|
+
|
|
225
|
+
After adding role enforcement to a router, grep for ALL write operations: `@router.post`, `@router.put`, `@router.patch`, `@router.delete` (or framework equivalent). Verify EVERY match has role checking. Don't just cover CRUD — also cover batch operations, merge endpoints, import/export, and admin utilities. (Field report #28: role enforcement added to 4 CRUD endpoints, missed 11 delete/batch/merge endpoints in the same router.)
|
|
226
|
+
|
|
227
|
+
### Auth Retrofit Audit
|
|
228
|
+
When adding new auth middleware, role checks, or authorization gates to a router or module, audit ALL existing endpoints in that same file/router for missing enforcement — not just the new ones. New auth patterns must be retrofitted to existing endpoints. Pre-existing write endpoints without role checks become privilege escalation vectors the moment auth is added to their neighbors.
|
|
229
|
+
(Field report #21: `_require_admin` added to new endpoints but not retrofitted to existing `PUT /settings/*` routes — any viewer could modify system config.)
|
|
230
|
+
|
|
231
|
+
**Padmé — Data:** PII identified. PII not in logs/errors/URLs. Deletion possible (GDPR). Export possible. Backups encrypted. **Anonymity invariant:** For apps with anonymous/alias features, verify BOTH response-level masking (alias shown instead of real name) AND query-level filtering (WHERE clauses must not match anonymous users by their real identity). Search endpoints, member lists, and autocomplete that filter by `displayName` or `email` create oracle attacks on anonymous identities. (Field report #36: response masking was correct but search WHERE clauses matched anonymous users by real displayName — 3 occurrences in one campaign.)
|
|
232
|
+
|
|
233
|
+
### No Secrets in Stored Data
|
|
234
|
+
|
|
235
|
+
Verify that no data written to the database contains API keys, tokens, or credentials embedded in URLs or values. Common pattern: an API adapter builds a URL with `&key=${apiKey}` and stores it in a database column. When that URL is served to clients, the API key leaks.
|
|
236
|
+
|
|
237
|
+
**Rule:** Stored URLs must never embed auth parameters. Proxy server-side instead — the client requests from your API, your API adds the credential at request time. (Field report #33: Google Places adapter stored photo URLs with embedded API key.)
|
|
238
|
+
|
|
239
|
+
### Filesystem Access Check
|
|
240
|
+
|
|
241
|
+
Flag any use of `readFile`, `readFileSync`, `writeFile`, `writeFileSync`, `createReadStream`, or `open` where the file path includes user-supplied input (request body, query params, URL segments). User-controlled paths enable path traversal — an attacker can read `/etc/passwd` or application secrets regardless of auth.
|
|
242
|
+
|
|
243
|
+
**Required controls for user-controlled file paths:**
|
|
244
|
+
1. `resolve()` + `normalize()` to canonicalize the path
|
|
245
|
+
2. Verify the resolved path starts with the expected base directory (allowlist, not blocklist)
|
|
246
|
+
3. Reject paths containing `..`, `~`, or null bytes
|
|
247
|
+
4. Use `realpath()` to resolve symlinks (see Symlink Resolution below)
|
|
248
|
+
|
|
249
|
+
(Field report #36: backfill endpoint accepted file path from request body, passed directly to `readFileSync`. Path traversal bypassed all auth.)
|
|
250
|
+
|
|
251
|
+
### Symlink Resolution
|
|
252
|
+
|
|
253
|
+
For every user-controlled file path, call `fs.realpath()` (or equivalent) after path string validation to resolve symlinks. Compare the resolved path against the expected base directory.
|
|
254
|
+
|
|
255
|
+
A path like `/opt/projects/legit` could be a symlink to `/etc/`. The `..` string check catches traversal in the path STRING but not symlink TARGETS. `resolve()` normalizes the string but does NOT resolve symlinks — only the OS does that during actual I/O.
|
|
256
|
+
|
|
257
|
+
**Pattern:**
|
|
258
|
+
```typescript
|
|
259
|
+
const dir = resolve(userInput); // Normalize string
|
|
260
|
+
if (dir.includes('..')) throw 'traversal'; // Fast string pre-check
|
|
261
|
+
const realDir = await realpath(dir); // Resolve symlinks via OS
|
|
262
|
+
if (!realDir.startsWith(expectedBase)) throw 'symlink escape';
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
(Field report #20: symlink bypass identified in Round 1, not fixed until Round 4.)
|
|
266
|
+
|
|
267
|
+
### Extended Star Wars Roster (activate as needed)
|
|
268
|
+
|
|
269
|
+
**Qui-Gon (Subtle Vulnerabilities):** Finds the vulnerabilities that pass every standard check — timing windows, race conditions in auth, logic errors that are technically correct but exploitable. "Always in motion is the future."
|
|
270
|
+
**Han (First Strike):** Quick OWASP top 10 scan before the deep audit begins. Shoots first — finds the obvious vulnerabilities that shouldn't require deep analysis.
|
|
271
|
+
**Anakin (Dark Side Exploitation):** After remediations, attempts to bypass them using framework misuse — JWT algorithm confusion, auth library edge cases, prototype pollution. "You underestimate my power."
|
|
272
|
+
**Bo-Katan (Perimeter Defense):** Network security, firewall rules, exposed ports, CORS policy, CSP headers. Guards the outer walls.
|
|
273
|
+
**Din Djarin (Bug Bounty):** Post-remediation bounty hunting. Hunts for any remaining vulnerability with Mandalorian tenacity. "This is the way."
|
|
274
|
+
**Bail Organa (Governance):** Compliance mapping — GDPR data handling, SOC2 controls, HIPAA if applicable. Not code-level security but policy-level compliance. Called for projects with regulatory requirements.
|
|
275
|
+
**Cassian (Intelligence):** Threat modeling and recon before anyone audits. Maps the attack surface, identifies high-value targets, produces the threat model that guides the rest of the audit.
|
|
276
|
+
**Sabine (Unconventional):** Tries attack vectors no standard checklist covers — supply chain attacks, dependency confusion, prototype pollution, CSP bypass via CDN. "You've never seen anyone fight like me."
|
|
277
|
+
|
|
278
|
+
### Browser-Based Security Checks (when E2E exists)
|
|
279
|
+
|
|
280
|
+
When E2E test infrastructure exists, Kenobi verifies in a real browser:
|
|
281
|
+
1. **Cookie inspection:** After authenticating, dump all cookies via `context.cookies()`. Flag: session cookies missing `HttpOnly`, missing `Secure`, missing `SameSite`. Use `inspectCookies()` from `browser-review.ts`.
|
|
282
|
+
2. **CORS verification:** Intercept API responses via `page.route()`. Check `Access-Control-Allow-Origin` headers. Flag wildcard `*` on authenticated endpoints. Use `captureCORSHeaders()`.
|
|
283
|
+
3. **CSP violation capture:** Monitor `securitypolicyviolation` events. Report each violation with the directive, blocked URI, and source. Use `captureCSPViolations()`.
|
|
284
|
+
4. **CSP execution verification:** After CSP headers are confirmed present, verify scripts actually *execute* under the policy. Navigate to a page with interactive functionality (form submission, client-side routing, dynamic content) and confirm it works — don't just check that the header exists. A nonce-based CSP that generates nonces in middleware but never passes them to the rendering framework produces correct headers with zero working scripts. Blank pages in production with no console errors (because CSP blocks silently) are the symptom. (Field report #259: nonce-based CSP wired in middleware but Next.js rendering never received nonces — every script blocked, blank pages in production.)
|
|
285
|
+
5. **Auth redirect verification:** Navigate to protected routes without session. Verify: redirect to login page (not 403 with content leak), no partial content rendered before redirect.
|
|
286
|
+
6. **Mixed content detection:** Monitor console for `Mixed Content` warnings during HTTPS navigation.
|
|
287
|
+
7. **Session fixation** — capture session token before login, complete login, verify a new session token is issued (old token invalidated)
|
|
288
|
+
|
|
289
|
+
These checks complement static code analysis — CSP and cookie attributes are often set by middleware/framework configuration that is invisible to grep-based auditing.
|
|
290
|
+
|
|
291
|
+
### Phase 3 — Remediate
|
|
292
|
+
|
|
293
|
+
Fix critical and high findings immediately. Medium findings get tracked. For each fix:
|
|
294
|
+
1. Apply the fix
|
|
295
|
+
2. Verify it works
|
|
296
|
+
3. Check it didn't break anything (`npm test`)
|
|
297
|
+
4. **Critical path smoke test:** After applying security fixes, verify the primary user flow still works. Security hardening that breaks core functionality is a regression, not an improvement. Common traps: stripping environment variables that the main tool needs (e.g., API keys), tightening auth that blocks legitimate users, restricting paths that the app needs to access, **removing `unsafe-inline` from CSP when framework-generated inline scripts exist in build output** (Next.js, Nuxt, SvelteKit all inject `<script>` tags at build time — invisible in source, fatal if blocked). If the fix breaks the happy path, the fix is wrong — find a way to secure without breaking.
|
|
298
|
+
5. Update the finding status
|
|
299
|
+
|
|
300
|
+
### Remediation Caller Tracing Rule
|
|
301
|
+
|
|
302
|
+
When fixing an auth, authorization, or validation check: trace ALL callers of the modified function AND find all code paths that implement the same check independently (inline duplicates). Don't fix only the helper — find the routes that duplicated the logic. When the fix changes a permission check in a shared function, grep for every endpoint that performs the same check with inline logic. (Field report #102: `checkMonthlyLimit()` was fixed to check BYOK tier, but the chat route had a separate inline BYOK resolution that wasn't updated.)
|
|
303
|
+
|
|
304
|
+
### Phase 4 — Re-Verify Remediations
|
|
305
|
+
|
|
306
|
+
After remediations are applied:
|
|
307
|
+
|
|
308
|
+
**Maul — Red Team Verification:** Re-probe all remediated vulnerabilities. Verify fixes hold under adversarial conditions. Check that fixes didn't introduce new attack vectors. Attempt to bypass the remediations.
|
|
309
|
+
|
|
310
|
+
**Padmé — Functional Verification:** After Maul confirms security holds, Padmé verifies the primary user flow still works end-to-end. Open the app, complete the main task, verify output. This catches "secure but broken" regressions that pure security re-testing misses.
|
|
311
|
+
|
|
312
|
+
Do not finalize the audit until both Maul AND Padmé sign off.
|
|
313
|
+
|
|
314
|
+
## Deliverables
|
|
315
|
+
|
|
316
|
+
1. SECURITY_AUDIT.md
|
|
317
|
+
2. SECURITY_CHECKLIST.md (reusable pre-deploy)
|
|
318
|
+
3. Finding tracker (prioritized)
|
|
319
|
+
4. Remediation fixes
|
|
320
|
+
5. INCIDENT_RESPONSE.md
|