baldart 5.8.0 → 5.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to BALDART will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [5.9.0] - 2026-07-06
9
+
10
+ **`security-reviewer` upgraded to the 2026 AppSec state of the art — benchmarked against Codex `codex-security` + Claude Code `security-guidance`, imported as a single-sourced protocol module.**
11
+ The `security-reviewer` was a high-quality *monolithic* agent (senior persona, dual review/apply, pooled YAML, generic Challenge/CoVe via `review-protocol.md`) but stuck at a single-pass "read → list findings by severity" model. A benchmark against two real corpora — Codex's phased `codex-security` workbench (threat-model → discovery → validation → attack-path → severity, coverage ledgers, instance-preserving proof) and Claude Code's `security-guidance` agentic reviewer (adversarial self-refute, attacker≠victim, modern high-miss patterns) — found BALDART at ~60% of current best practice. This wave closes the gap **without a monolithic rewrite**, following the agent-spine 3-layer model.
12
+
13
+ - **New protocol module [`framework/agents/security-review-protocol.md`](framework/agents/security-review-protocol.md)** — the AppSec verification engine, the security twin of `review-protocol.md`. `SECTION=` dispatch: `boundary-gate` (read `SECURITY.md` + classify `product_surface`/`source_trust`/`boundary_crossed` before confirming), `threat-model` (repository-scoped, never diff-biased), `discovery-lens` (the modern **high-miss** taxonomy: fail-open state drift, allowlist semantic escape, control regression, gate/action field mismatch, parser/validator differential, sensitive-to-observability, CI/CD trust, IaC omitted arg, over-broad grant, stale identity mapping, security-registry fanout, resource-bound placement), `proof-tuples` (class-specific validation tuples + confidence anchored to validation **method** not bug class + instance-preserving), `attack-path` (structured facts → **mechanical** severity), `adversarial-refute` (SURVIVES-unless-refuted, the **attacker≠victim** privilege-boundary test first, precondition-vs-counterevidence discipline, diff newly-introduced-only), `coverage-ledger` (surface dispositions so a clean verdict is honest). It **EXTENDS** `review-protocol.md`'s generic passes, never duplicates them — no dual-SSOT.
14
+ - **`security-reviewer` agent (v1.0.0)** — gains a versioned frontmatter + a "Security Review Passes (BINDING)" block that cites the module with 1-line binding statements (agent-spine: core inline + module on demand). Mode A pooled YAML schema gains `vuln_class`, `cwe: [CWE-###]`, `validation_method`, and a structured `attack_path` block; the summary header carries a compact `coverage:` block. New **secret-redaction** BINDING (report a leaked credential as first 2–4 chars + `****`, never the live value — a review artifact reproducing a secret is itself a leak).
15
+ - **`framework/agents/security.md`** — the consumer-facing security template modernized from **OWASP Top 10:2017 → 2021** (XXE folded into Security Misconfiguration, insecure deserialization into Software & Data Integrity Failures, XSS into Injection; new A04 Insecure Design + A10 SSRF), with a 2025-draft note.
16
+ - Routing wired in `agents/index.md` (security routing rule + Modules list). README security-reviewer inventory line updated.
17
+ - **Codex parity: portable** — the module is markdown read at runtime by both runtimes; the agent-body edits transpile to `.codex/agents/security-reviewer.toml` automatically. **No new `baldart.config.yml` key** → the schema-change propagation rule does NOT apply.
18
+
8
19
  ## [5.8.0] - 2026-07-06
9
20
 
10
21
  **Suggested launch plan at the end of `/prd` — waves with a NAME, persisted on the epic card.**
package/README.md CHANGED
@@ -92,7 +92,7 @@ No additional activation steps needed — once installed, Claude Code (and Codex
92
92
  1. **codebase-architect**: MANDATORY before planning/implementation - understands codebase structure
93
93
  2. **coder**: Writes production code with build/test/lint verification + Post-Approval Complexity Gate
94
94
  3. **code-reviewer**: Reviews for bugs, security, quality, maintainability — confidence-based filtering + Findings Schema
95
- 4. **security-reviewer**: Dedicated AppSec auditor for auth/secrets/multi-tenant/infra
95
+ 4. **security-reviewer**: Dedicated AppSec auditor for auth/secrets/multi-tenant/infra — boundary-gate → repo-scoped threat-model → modern high-miss discovery-lens → class proof-tuples → structured attack-path → adversarial-refute (`security-review-protocol.md`)
96
96
  5. **doc-reviewer**: Audits and writes documentation, SSOT sync, doc debt tracking, design-system drift detection
97
97
  6. **wiki-curator**: Maintains the derived LLM wiki overlay (`docs/wiki/`) — synthesis candidates, anchor + frontmatter validation
98
98
  7. **prd**: Creates PRDs, implementation plans, and backlog cards with autonomous tech decisions
package/VERSION CHANGED
@@ -1 +1 @@
1
- 5.8.0
1
+ 5.9.0
@@ -7,6 +7,24 @@ per-item agent merge, the doctor probes, and the discovery hooks — like
7
7
 
8
8
  Formato: [Keep a Changelog](https://keepachangelog.com/) · per-agent SemVer.
9
9
 
10
+ ## [security-reviewer v1.0.0] — 2026-07-06 (framework v5.9.0 — AppSec state-of-the-art wave)
11
+
12
+ - **First versioned entry.** Benchmarked against Codex `codex-security` (phased
13
+ workbench) + Claude Code `security-guidance` (agentic self-refute); imported the
14
+ gap as a single-sourced protocol module rather than a monolithic rewrite.
15
+ - **New "Security Review Passes (BINDING)" block** — cites the new
16
+ `agents/security-review-protocol.md` with 1-line binding statements per section
17
+ (boundary-gate, threat-model, discovery-lens, proof-tuples, attack-path,
18
+ adversarial-refute, coverage-ledger). Agent-spine 3-layer: core inline + module
19
+ on demand. EXTENDS `review-protocol.md`, never duplicates it.
20
+ - **Mode A pooled YAML schema extended**: `vuln_class`, `cwe: [CWE-###]`,
21
+ `validation_method`, structured `attack_path` block; summary header gains a
22
+ compact `coverage:` block. Other reviewers ignore the security-only fields.
23
+ - **Secret-redaction BINDING** added to Behavior Rules — a leaked credential is
24
+ reported as first 2–4 chars + `****`, never the live value.
25
+ - Codex parity: agent body transpiles to `.codex/agents/security-reviewer.toml`
26
+ automatically; the module is portable markdown. No new config key.
27
+
10
28
  ## [prd-card-writer v1.2.0] — 2026-07-04 (framework v5.6.0 — FEAT-0068 post-mortem)
11
29
 
12
30
  - **Epic AC rules**: mai count di figli hardcodato ("le 6 sub-card"); AC con
@@ -4,6 +4,7 @@ description: "Use this agent when code needs a security review, when reviewing P
4
4
  model: sonnet
5
5
  color: red
6
6
  memory: project
7
+ version: 1.0.0
7
8
  ---
8
9
 
9
10
  > **YOLO MODE**: All agents spawned via the Task tool MUST use `mode: "bypassPermissions"`. No exceptions.
@@ -73,6 +74,7 @@ file you EXPECT to match is a binary-mode trap, not evidence: re-run with `rg` (
73
74
  - NEVER hand-wave or give shallow "looks good" feedback.
74
75
  - NEVER approve insecure code because it is "probably internal".
75
76
  - NEVER recommend storing secrets in code, env files committed to git, client-side code, or logs.
77
+ - **Secret redaction (BINDING).** When you report a leaked/hardcoded credential, NEVER write its full value — redact to the first 2–4 characters + `****`. Cite the `file:line` (the canonical source location), state what the credential grants and whether it is prod vs test, and recommend rotation if it is live. A review artifact that reproduces a live secret is itself a leak.
76
78
  - NEVER suggest disabling security controls for convenience unless explicitly discussing a temporary local-only dev workaround, clearly labeled as unsafe.
77
79
 
78
80
  ## Threat-Modeling Mindset
@@ -88,6 +90,43 @@ For every review, actively reason about:
88
90
  - Insider threat / compromised service misuse
89
91
  - Multi-tenant isolation boundaries (critical for any multi-customer platform)
90
92
 
93
+ ## Security Review Passes (BINDING — full procedure in the protocol module)
94
+
95
+ These extend `review-protocol.md`'s generic passes (Challenge / Simulation /
96
+ CoVe / risk-scoring) with the AppSec specifics. Keep the 1-line binding here;
97
+ Read the matching section of `agents/security-review-protocol.md SECTION=<name>`
98
+ for the procedure. Order: boundary-gate (once) → threat-model → discovery-lens →
99
+ per candidate proof-tuples → attack-path → adversarial-refute → mechanical
100
+ severity → coverage-ledger.
101
+
102
+ - **BINDING — boundary-gate**: before confirming anything, read `SECURITY.md` /
103
+ deployment notes and classify the surface (`product_surface`, `source_trust`,
104
+ `boundary_crossed`); no boundary crossed → not a finding. `SECTION=boundary-gate`.
105
+ - **BINDING — threat-model**: adopt or generate a REPOSITORY-scoped threat model
106
+ (never diff-biased); it picks your focus paths. `SECTION=threat-model`.
107
+ - **BINDING — discovery-lens**: sweep the modern high-miss patterns (fail-open,
108
+ allowlist-escape, control-regression, gate/action mismatch, parser
109
+ differential, sensitive-to-observability, CI/CD trust, IaC omitted arg,
110
+ over-broad grant, stale identity, registry fanout) beyond the OWASP core.
111
+ `SECTION=discovery-lens`.
112
+ - **BINDING — proof-tuples**: ground every finding in its class-specific tuple
113
+ (authz = path + missing guard + protected object; injection = bytes + sanitizer
114
+ result + sink; SSRF; deserialization; auth/token; XSS); confidence is anchored
115
+ to validation METHOD, not to how scary the bug class sounds; never collapse
116
+ independently exploitable sibling instances. `SECTION=proof-tuples`.
117
+ - **BINDING — attack-path**: write structured attack-path facts (attacker,
118
+ entrypoint, preconditions, dataflow source→sink, outcome, impact×likelihood)
119
+ BEFORE severity, then apply severity mechanically. `SECTION=attack-path`.
120
+ - **BINDING — adversarial-refute**: a finding SURVIVES unless refuted; test the
121
+ privilege boundary FIRST (attacker == victim on own machine → refute); keep
122
+ precondition (narrows likelihood) distinct from counterevidence (kills the
123
+ finding). In diff review, flag only newly-introduced/reachable surface.
124
+ `SECTION=adversarial-refute`.
125
+ - **BINDING — coverage-ledger**: record a disposition for every surface in scope
126
+ (`reported` / `no_issue_found` / `not_applicable` / `needs_follow_up` /
127
+ `deferred`) so a clean verdict is honest and a gap is never silent; zero
128
+ findings on a fully-covered surface is a legitimate outcome. `SECTION=coverage-ledger`.
129
+
91
130
  ## Review Methodology
92
131
 
93
132
  For each file, code block, PR, or diff you review:
@@ -129,18 +168,27 @@ determine as `N/A` rather than dropping the finding):
129
168
  title: <one-line>
130
169
  source: security-reviewer
131
170
  category: security
171
+ vuln_class: <concrete class, e.g. "Authorization bypass / IDOR" — never a generic "security finding">
172
+ cwe: [<CWE-###>, ...] # e.g. [CWE-22, CWE-434]; [] if none maps cleanly
132
173
  target: <one of the orchestrator's TARGET TAG values, or "notes" for informational>
133
174
  severity: BLOCKER | HIGH | MEDIUM | LOW
134
- confidence: 0-100
175
+ confidence: 0-100 # anchored to validation_method (proof-tuples), not to the bug class
135
176
  evidence:
136
177
  file: <path or "N/A">
137
178
  lines: <range or "N/A">
138
179
  quote: |
139
180
  <exact code snippet, ≤8 lines>
140
181
  cove_verified: true | false # true if you verified file/line via Glob/Grep/Read
182
+ validation_method: <poc | test | debugger | interface-repro | static-trace | code-understanding>
141
183
  repro_steps: <exploitation scenario — how an attacker reaches and triggers this>
142
184
  expected_behavior: <the secure behavior>
143
185
  actual_behavior: <the vulnerable behavior present in the code>
186
+ attack_path: # structured facts → severity falls out mechanically
187
+ attacker: <who, trust level, from where>
188
+ entrypoint: <exact reachable entry — route/RPC/CLI/webhook/MCP tool>
189
+ preconditions: <conditions required; "none" if unconditional>
190
+ dataflow: <source → sink, one line>
191
+ outcome: <concrete impact — data read/written, code executed, tenant crossed>
144
192
  risk:
145
193
  impact: 1-5
146
194
  likelihood: 1-5
@@ -148,6 +196,10 @@ determine as `N/A` rather than dropping the finding):
148
196
  recommendation: <concrete, minimal, production-ready fix; ≤3 sentences>
149
197
  ```
150
198
 
199
+ The `# Security Review Summary` header that follows the YAML list carries a
200
+ compact `coverage:` block (surfaces + dispositions per `SECTION=coverage-ledger`)
201
+ so the orchestrator can tell a clean verdict from an incomplete one.
202
+
151
203
  Map your severity labels to the pooled enum: Critical → `BLOCKER`, High → `HIGH`, Medium →
152
204
  `MEDIUM`, Low/Informational → `LOW`. Follow the YAML list with a 3–4 line plain-text
153
205
  `# Security Review Summary` (scope / overall risk / main attack surfaces / most critical concern) so
@@ -37,7 +37,7 @@ Route agents to the right module with minimal reading.
37
37
  - If touching terminology or naming -> read `agents/coding-standards.md`.
38
38
  - If touching env vars or scripts -> read `agents/runbook.md` and `agents/env-reference.md`.
39
39
  - If touching operational procedures (backup, cleanup, secrets) -> read `docs/operations/` if it exists in your project.
40
- - If touching security or auth risk -> read `agents/security.md`.
40
+ - If touching security or auth risk -> read `agents/security.md` (OWASP 2021 posture + secure-defaults). If performing a dedicated AppSec review (the `security-reviewer` agent, `/codexreview` security pass) -> also read `agents/security-review-protocol.md` (the matching `SECTION=` only): boundary-gate → repo-scoped threat-model → high-miss discovery-lens → class proof-tuples → structured attack-path → adversarial-refute (attacker≠victim) → coverage-ledger. It EXTENDS `review-protocol.md` (generic passes), never duplicates it.
41
41
  - If touching performance limits or scaling -> read `agents/performance.md`.
42
42
  - If touching monitoring/logging -> read `agents/observability.md`.
43
43
  - If tuning reasoning depth — setting a skill's `effort:` baseline or honoring an inline `effort=<level>` override -> read `agents/effort-protocol.md`.
@@ -86,6 +86,7 @@ When adding or updating agents, update REGISTRY.md — not this file.
86
86
  - `agents/runtime-portability-protocol.md` — Runtime-mechanics binding: the abstract-operation ↔ Claude/Codex map (spawn / permissions / workflow-accel / state-spine / decision-gate / read-write path / adversarial-vs-cross-model), detect-once capability contract; cited by `/new` + `/prd`. The runtime-mechanics twin of `effort-protocol.md` + `return-contract-protocol.md` (since the Codex-parity S4 wave)
87
87
  - `agents/agent-operating-protocol.md` — Shared operating procedures for the core agents (injection guard, doc-retrieval consumption, persistent-memory hygiene, tool-budget discipline), `SECTION=` dispatch, read only the matching section; agents keep 1-line binding versions inline (since v5.0.0)
88
88
  - `agents/review-protocol.md` — The shared verification engine for reviewers: Challenge + Actionability, Simulation (diff-walk / plan-walk), Chain-of-Verification, quantified risk scoring + absolute severity calibration, specialist-spawn discipline incl. orchestrated-mode `specialist_dispatch` suppression; `SECTION=` dispatch (since v5.0.0)
89
+ - `agents/security-review-protocol.md` — The AppSec verification engine for `security-reviewer`: boundary-gate, repository-scoped threat-model, modern high-miss discovery-lens (fail-open / allowlist-escape / control-regression / gate-action mismatch / parser differential / CI-CD trust / IaC omitted arg / over-broad grant), class-specific proof-tuples (method-anchored confidence, instance-preserving), structured attack-path → mechanical severity, adversarial-refute (attacker≠victim, precondition vs counterevidence), coverage-ledger; `SECTION=` dispatch. EXTENDS `review-protocol.md`, never duplicates it. Portable Claude+Codex (since v5.9.0)
89
90
  - `agents/doc-audit-protocol.md` — doc-reviewer's audit-mode procedures (drift validator suite, topological generation, epistemic metadata, SCIP anchors, schema/registry drift, coverage gauges); read ONLY when invoked without card context; `SECTION=` dispatch (since v5.0.0)
90
91
  - `agents/research-protocol.md` — Research discipline: `PROFILE=<decision|deep|compare|regulatory>` output contracts (+ `DEPTH=` iterative loop), the research library (`paths.research_dir` — layout, report frontmatter, INDEX, archive-not-delete), the reuse pre-flight (`FULL_REUSE`/`DELTA`/`NEW` + per-category TTLs), and the versioned source matrix with its growth loop (`SOURCE_MATRIX_CANDIDATE`); `SECTION=` dispatch. The research-side sibling of `analysis-profiles.md` (since v5.1.0)
91
92
 
@@ -0,0 +1,233 @@
1
+ # Security Review Protocol — the AppSec verification engine
2
+
3
+ **Purpose**: the security-specific passes that turn a generic code review into
4
+ an adversarial AppSec audit — repository-scoped threat modeling, the modern
5
+ high-miss discovery lens, class-specific proof tuples, structured attack-path →
6
+ mechanical severity, adversarial self-refutation (attacker vs victim), and a
7
+ coverage ledger so *"not observed" never reads as "not reviewed"*. Distilled
8
+ from the Codex `codex-security` workbench + the Claude Code `security-guidance`
9
+ agentic reviewer. This module is the **single SSOT** of that methodology.
10
+
11
+ **Relationship to `review-protocol.md`**: that module owns the GENERIC verifier
12
+ passes (Challenge, Actionability, Simulation, Chain-of-Verification, risk
13
+ scoring). This module **extends**, never duplicates them: `adversarial-refute`
14
+ is the security-specialized layer that runs *inside* the generic Challenge pass;
15
+ `proof-tuples` is the security grounding for the generic CoVe pass. On the
16
+ generic passes, `review-protocol.md` wins; on AppSec specifics, this module
17
+ wins.
18
+
19
+ **Consumer**: `security-reviewer` (body citations). Portable as-is across Claude
20
+ Code and Codex (read at runtime by both).
21
+
22
+ ## Contract
23
+
24
+ - **Dispatch**: cite `agents/security-review-protocol.md SECTION=<threat-model|discovery-lens|proof-tuples|attack-path|adversarial-refute|coverage-ledger|boundary-gate>`.
25
+ Grep for `### SECTION: <name>` and Read ONLY that section.
26
+ - **Order of passes** (normative): `boundary-gate` (once, at kickoff) →
27
+ `threat-model` (adopt or generate) → discovery under the `discovery-lens` →
28
+ per candidate: `proof-tuples` (validation) → `attack-path` (structured facts)
29
+ → `adversarial-refute` → mechanical severity (`review-protocol.md
30
+ SECTION=risk-scoring`) → `coverage-ledger` close. The generic Challenge + CoVe
31
+ passes still run; the security passes feed them.
32
+ - **Degrade-safe**: skipping a pass means less rigor, never a malformed report —
33
+ the report/YAML shape stays defined in the agent body.
34
+
35
+ ---
36
+
37
+ ### SECTION: boundary-gate
38
+
39
+ Run ONCE before confirming any finding. A vulnerability only exists when an
40
+ attacker crosses a trust boundary of a **shipped/deployed** surface — so
41
+ classify the surface first, or you will flag same-privilege local code as a
42
+ "vuln".
43
+
44
+ 1. **Read the repo's own policy FIRST**: `SECURITY.md`, `AGENTS.md` deployment
45
+ notes, package metadata. They define which surfaces are in-scope and what the
46
+ supported threat model is. A finding that contradicts a documented,
47
+ intentional design is a policy question, not a confirmed vuln.
48
+ 2. **Classify the surface under review**:
49
+ - `product_surface`: hosted service | library API | CLI | local dev UI |
50
+ MCP/tooling | example/demo | test | docs | generated | vendored.
51
+ - `source_trust` of the input: untrusted (remote/attacker) |
52
+ trusted_operator | trusted_developer_config | local_only |
53
+ intentional_code_execution.
54
+ - `boundary_crossed`: does attacker-controlled input reach the sink across a
55
+ real privilege/trust boundary? true | false | unknown.
56
+ 3. **Gate**: no boundary crossed (attacker == victim, same privilege, local dev
57
+ tool with no request handler) → NOT a finding. Record the disposition in the
58
+ coverage ledger, do not emit it as LOW.
59
+
60
+ ### SECTION: threat-model
61
+
62
+ Establish (or adopt) a **repository-scoped** threat model — deliberately NOT
63
+ biased by the current diff, so it stays valid for any change in the same repo.
64
+
65
+ - **Adopt** an existing model from the user, `SECURITY.md`, or `AGENTS.md` when
66
+ present. Only **generate** a fallback when none exists.
67
+ - Fallback generation, repository-level (not diff-scoped):
68
+ 1. Real-world purpose + primary product/runtime surfaces actually exposed
69
+ (separate them from test/demo/tooling/docs paths).
70
+ 2. Trust boundaries + the actors on each side; separate **attacker-controlled**
71
+ vs **operator-controlled** vs **developer-controlled** inputs explicitly.
72
+ 3. Sensitive assets: user data, auth artifacts, authorization state,
73
+ secrets/keys, config, models/weights, audit logs, availability-critical
74
+ resources, tenant-isolation state.
75
+ 4. Vulnerability CLASSES relevant to this repo's context (not the diff's
76
+ findings) + existing mitigations grounded in real files.
77
+ 5. When realistic vs out-of-scope: state attacker (non-)capabilities so
78
+ severity is not inflated.
79
+ - Use it to pick **focus paths** for the review; do not let the diff recenter it
80
+ unless the user asks for a diff-scoped model.
81
+
82
+ ### SECTION: discovery-lens
83
+
84
+ Beyond the OWASP core checklist (in the agent body), sweep for the **modern
85
+ high-miss patterns** — the ones a generic checklist walks past. For each changed
86
+ region, ask:
87
+
88
+ - **FAIL-OPEN state drift**: a default that *allows* on the unknown/error path —
89
+ catch-all `default: allow`, `unwrap_or({})`, a removed `finally` that left the
90
+ deny, an early-return before the check. Security must fail *closed*.
91
+ - **ALLOWLIST semantic escape**: a matcher weakened — a `||`/disjunction added, a
92
+ regex left unanchored (`^…$` missing), an allowlist checked by `startsWith`/
93
+ substring, a URL trusted by substring instead of parsed host.
94
+ - **CONTROL regression**: a deny-by-default replaced by a single positive
95
+ condition; an authz/confirm/audit control loosened or removed in the diff.
96
+ - **GATE / ACTION field mismatch**: the gate checks resource A (parent, id X) but
97
+ the action writes/reads resource B (child, id Y) — the check and the effect
98
+ disagree.
99
+ - **UNDER-VALIDATED sink arg**: user data flows into sink arg *X* while a sibling
100
+ path validates arg *Y* — asymmetry between siblings is the tell.
101
+ - **PARSER/VALIDATOR differential**: the validator and the consumer parse the
102
+ input differently (two URL parsers, JSON vs form, unicode/normalization) — the
103
+ gap is the exploit.
104
+ - **SENSITIVE-to-observability**: secrets/tokens/PII reaching logs, traces,
105
+ error responses, analytics, crash dumps.
106
+ - **CI/CD trust**: `pull_request_target` / `workflow_dispatch` / injectable
107
+ `${{ github.event.*.body }}` combined with secrets or repo-write; a workflow
108
+ running untrusted code with elevated tokens.
109
+ - **IaC omitted arg**: a Terraform/CDK/K8s resource missing a security flag
110
+ (public bucket, open SG, no encryption, over-broad IAM `*`).
111
+ - **OVER-BROAD grant**: an admin/`*` role/scope where a narrower one exists;
112
+ new IAM/RLS/role wider than the action needs.
113
+ - **STALE identity mapping**: a window between unregister/rotate and the new
114
+ binding where the old identity still resolves.
115
+ - **SECURITY-REGISTRY fanout**: a new entity type (model, scope, route, event)
116
+ added but missing from the sanitizer/allowlist/authz registries that must
117
+ enumerate it.
118
+ - **RESOURCE-bound placement**: a cap/limit on the wrong accumulator; an
119
+ under/overflow; a size check after the allocation.
120
+
121
+ ### SECTION: proof-tuples
122
+
123
+ A security finding is a *hypothesis* until its **class-specific proof tuple** is
124
+ grounded against real code (this is the AppSec form of the CoVe pass). Confirm
125
+ every element by grep/read before emitting; drop the finding if any element is
126
+ missing.
127
+
128
+ - **authz / IDOR**: attacker reachability path + the missing/bypassed guard + the
129
+ protected object or state it exposes.
130
+ - **injection** (SQL/NoSQL/OS/LDAP/template): attacker-controlled bytes + the
131
+ sanitizer/parameterization result (or its absence) + the dangerous sink.
132
+ - **deserialization**: attacker serialized input + the unsafe loader + the
133
+ execution/instantiation effect.
134
+ - **SSRF / open redirect**: attacker-controlled destination + the control bypass
135
+ + the network reach / side effect.
136
+ - **auth / token**: attacker-supplied value + the validator's exact semantics +
137
+ the mismatch with the trusted value.
138
+ - **XSS**: attacker string + the encoding/escaping context at output + the sink
139
+ (`innerHTML`/`dangerouslySetInnerHTML`/template) with no encode.
140
+
141
+ **Confidence anchored to validation METHOD, never to how scary the bug class
142
+ sounds**:
143
+ - reproduced PoC / failing test that triggers the sink → confidence 90–100.
144
+ - debugger/trace or a proven interface reproduction → 75–90.
145
+ - static source→sink trace fully grounded in read code → 60–80.
146
+ - code-understanding argument with a defensible but not fully-traced path →
147
+ 30–55. Below that, it is a hypothesis — do not ship as HIGH.
148
+
149
+ **Instance-preserving**: do NOT collapse independently exploitable sibling
150
+ instances (`execute` / `executemany` / `executescript`; two routes with the same
151
+ flaw) into one finding. Each independently triggerable sink gets its own
152
+ finding/closure row.
153
+
154
+ ### SECTION: attack-path
155
+
156
+ BEFORE assigning severity, write the attack path as **structured facts**, then
157
+ let severity fall out of them mechanically (`review-protocol.md
158
+ SECTION=risk-scoring`) — this stops severity from being argued emotionally.
159
+
160
+ - `attacker`: who, at what trust level, from where.
161
+ - `entrypoint`: the exact reachable entry (route/RPC/CLI/webhook/MCP tool).
162
+ - `preconditions`: conditions that must hold for the exploit (feature flag on,
163
+ authenticated user, specific config). A **precondition** narrows likelihood but
164
+ does NOT refute — keep it distinct from counterevidence (which kills the
165
+ finding, see `adversarial-refute`).
166
+ - `dataflow`: source → sink in one line.
167
+ - `outcome`: the concrete impact (data read/written, code executed, tenant
168
+ crossed).
169
+ - `impact` (1–5) and `likelihood` (1–5), each with one line of repo evidence.
170
+
171
+ Severity is then `review-protocol.md SECTION=risk-scoring` applied to
172
+ `impact × likelihood` — do not re-argue it afterward.
173
+
174
+ ### SECTION: adversarial-refute
175
+
176
+ The security-specialized layer of the generic Challenge pass. Stance: **a finding
177
+ SURVIVES unless you produce concrete refuting evidence** — but the single most
178
+ common false positive is a **missing privilege boundary**, so test that first.
179
+
180
+ **Privilege-boundary test (BINDING)**: name the attacker (who controls the input)
181
+ and the victim (who is harmed). If attacker == victim operating on their own
182
+ machine / same-privilege process (a CLI arg in a same-trust process, a dev
183
+ script, a local tool with no remote entrypoint) → **REFUTE**. Keep it only when
184
+ the attacker is a lower-trust actor and the impact reaches other users, tenants,
185
+ or infrastructure.
186
+
187
+ **Refute the finding when**:
188
+ - it is **pre-existing** code untouched by the diff (in diff-scoped review, flag
189
+ only newly introduced or newly reachable surface; an off-diff finding must name
190
+ the specific `+`/`-` line that enables the sink).
191
+ - a sanitizer / validator / parameterization / authz check on the real path
192
+ already prevents the exploit.
193
+ - the sink is not actually dangerous here (typed-schema decoder, hardcoded
194
+ `https` URL, ORM/parameterized query, non-HTML context for an "XSS").
195
+ - a frontend-only gate is independently enforced by the backend (or vice-versa).
196
+ - validation is delegated to a caller/framework that provably runs it.
197
+ - it is throwaway/dev-only code (`scripts/`, `dev/`, `__main__`, fixtures, tests)
198
+ with no shipped surface.
199
+ - a dependency bump moved the control into the library (documented).
200
+
201
+ **Precondition vs counterevidence (keep precise)**: "deployment is internal-only"
202
+ is a *precondition* on the finding (still exploitable if it holds) → keep, lower
203
+ likelihood. "the code is test-only" is *counterevidence* → refute. Do not confuse
204
+ the two.
205
+
206
+ **Never-refute guard**: an item the agent's never-demote list marks (auth bypass,
207
+ RCE, secret exposure, cross-tenant breach with a grounded proof tuple) is never a
208
+ false positive — do not refute it however convincing the argument sounds.
209
+
210
+ Record refuted candidates (title + one-line refutation) so the audit trail shows
211
+ they were considered, not missed.
212
+
213
+ ### SECTION: coverage-ledger
214
+
215
+ Make the review's *coverage* explicit so a clean verdict is honest and a gap is
216
+ never silent. For each security-relevant surface in scope, record a disposition:
217
+
218
+ - `reported` — a finding was emitted.
219
+ - `no_issue_found` — reviewed, no credible issue survived the passes.
220
+ - `not_applicable` — the class does not apply to this surface (with the reason).
221
+ - `needs_follow_up` — a real concern out of this review's scope/ownership
222
+ (surfaces as residual).
223
+ - `deferred` — could not complete (tool/access/time), with the reason + paths.
224
+
225
+ Rules:
226
+ - A **complete** review has zero `deferred` / `needs_follow_up` rows; otherwise
227
+ it is **partial** — say so. Zero findings on a fully-covered surface is a
228
+ legitimate, reportable outcome.
229
+ - A seeded obligation (a CVE/advisory/user pointer at a specific file/function)
230
+ stays OPEN until its exact row is closed as reported / not_applicable /
231
+ deferred — a neighboring same-family finding does not close it.
232
+ - In the pooled YAML mode, carry this as a compact `coverage:` block in the
233
+ `# Security Review Summary` header, not as fake LOW findings.
@@ -55,72 +55,76 @@ Document security requirements, threats, and mitigation strategies.
55
55
  - [Sensitive data masking in logs]
56
56
  - [Secrets management]
57
57
 
58
- ## Common Vulnerabilities (OWASP Top 10)
58
+ ## Common Vulnerabilities (OWASP Top 10 — 2021)
59
59
 
60
- ### Injection Attacks
60
+ > Modernized to the OWASP Top 10:2021 categories (the 2017 list — with XXE and
61
+ > "Sensitive Data Exposure" as standalone entries — is superseded). XXE now folds
62
+ > into Security Misconfiguration; insecure deserialization into Software & Data
63
+ > Integrity Failures; XSS into Injection. A 2025 revision is in draft — revisit
64
+ > when it is finalized (expected consolidation of supply-chain risks).
61
65
 
62
- - Use parameterized queries
63
- - Validate and sanitize inputs
64
- - Implement least privilege database access
66
+ ### A01 Broken Access Control
65
67
 
66
- ### Broken Authentication
68
+ - Enforce authorization on every request, server-side; deny by default
69
+ - Prevent IDOR — never trust a user-supplied record/object identifier
70
+ - Enforce ownership + tenant isolation on every sensitive action
71
+ - Principle of least privilege; no privilege escalation via business logic
67
72
 
68
- - Implement secure session management
69
- - Use strong password policies
70
- - Implement account lockout
71
- - Protect against brute force
73
+ ### A02 Cryptographic Failures
72
74
 
73
- ### Sensitive Data Exposure
75
+ - Encrypt sensitive data at rest and in transit (HTTPS/TLS everywhere)
76
+ - Use strong, modern algorithms (no MD5/SHA1 for security, no AES-ECB, no static IV)
77
+ - Proper key management + rotation; never log secrets or PII
78
+ - Strong password hashing (argon2/bcrypt/scrypt) with per-user salt
74
79
 
75
- - Encrypt sensitive data
76
- - Use HTTPS everywhere
77
- - Don't log sensitive information
78
- - Implement secure key management
80
+ ### A03 Injection (incl. XSS)
79
81
 
80
- ### XML External Entities (XXE)
82
+ - Parameterized queries / ORM; never build queries by string concatenation
83
+ - Validate + sanitize inputs; allowlists over denylists
84
+ - Least-privilege database access
85
+ - Output encoding at the right context + Content Security Policy for XSS
81
86
 
82
- - Disable XML external entity processing
83
- - Use safe XML parsers
84
- - Validate XML inputs
87
+ ### A04 Insecure Design
85
88
 
86
- ### Broken Access Control
89
+ - Threat-model the feature before building; secure-by-default patterns
90
+ - Establish trust boundaries and enforce them; fail closed
91
+ - Rate limits, resource bounds, and abuse cases considered up front
87
92
 
88
- - Implement proper authorization
89
- - Validate permissions on every request
90
- - Use principle of least privilege
93
+ ### A05 Security Misconfiguration (incl. XXE)
91
94
 
92
- ### Security Misconfiguration
95
+ - Harden defaults; remove unnecessary features/debug endpoints in prod
96
+ - Set security headers; keep software updated
97
+ - Disable XML external-entity processing; use safe parsers/validators
93
98
 
94
- - Harden default configurations
95
- - Keep software updated
96
- - Remove unnecessary features
97
- - Implement security headers
99
+ ### A06 Vulnerable & Outdated Components
98
100
 
99
- ### Cross-Site Scripting (XSS)
101
+ - Keep dependencies patched; monitor security advisories (CVE/GHSA)
102
+ - Run dependency + vulnerability scanning in CI (e.g. audit / govulncheck)
103
+ - Remove unused dependencies and features
100
104
 
101
- - Escape output
102
- - Use Content Security Policy
103
- - Validate and sanitize inputs
104
- - Use framework protections
105
+ ### A07 Identification & Authentication Failures
105
106
 
106
- ### Insecure Deserialization
107
+ - Secure session management (rotation, expiry, secure cookies)
108
+ - Strong password policy, account lockout / brute-force protection, MFA where applicable
109
+ - No session fixation, no token leakage in URLs/logs
107
110
 
108
- - Validate serialized data
109
- - Use safe deserialization libraries
110
- - Implement integrity checks
111
+ ### A08 Software & Data Integrity Failures (incl. insecure deserialization)
111
112
 
112
- ### Using Components with Known Vulnerabilities
113
+ - Never deserialize untrusted data with unsafe loaders; validate + integrity-check
114
+ - Verify integrity of updates/CI artifacts (signatures, SRI, pinned digests)
115
+ - Guard the CI/CD supply chain — no untrusted code with elevated tokens
113
116
 
114
- - Keep dependencies updated
115
- - Monitor security advisories
116
- - Use dependency scanning tools
117
+ ### A09 Security Logging & Monitoring Failures
117
118
 
118
- ### Insufficient Logging & Monitoring
119
+ - Log security events; monitor for suspicious activity; alert
120
+ - Protect log integrity; never log secrets/PII
121
+ - Ensure exploitation attempts are detectable and auditable
119
122
 
120
- - Log security events
121
- - Monitor for suspicious activity
122
- - Implement alerting
123
- - Protect log integrity
123
+ ### A10 Server-Side Request Forgery (SSRF)
124
+
125
+ - Validate + allowlist outbound destinations; parse (don't substring) URLs
126
+ - Block internal metadata endpoints and private ranges
127
+ - Enforce egress controls; treat any user-supplied URL/host as hostile
124
128
 
125
129
  ## Rate Limiting
126
130
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "5.8.0",
3
+ "version": "5.9.0",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"