feat(arsenal): parse scanner JSON into structured findings (#42)
The generic adapter factory returned raw stdout only (`adapter-tools.ts` success path), so 35 catalogued scanners with `parserStatus: 'planned'` never populated the structured `ToolResult.findings` channel — their output was dropped on the floor and the agent could neither verify nor chain on it. The whole downstream pipe already exists and is honest-by-construction: the agent loop stamps `provenance:'tool'` + the raw output, the operator materialises each finding with output-evidence, and the live gate (`evidence/gate.ts`) marks it verified. Add `src/arsenal/parsers.ts` — `parseToolOutput(toolId, rawStdout) → ToolFinding[]` for the five scanners that already emit machine-readable JSON via their existing arg templates (zero template changes): nuclei (-jsonl), httpx (-json), dalfox (--format json), ffuf (-of json), katana (-jsonl). Parsers are pure, dependency-free, and NEVER throw: empty/garbled/unknown input yields `[]`, never a fabricated finding (same discipline as stub-honesty / no-phantom-tools). The factory attaches parsed findings while ALWAYS keeping the raw stdout as `output` — the evidence of record the gate checks. - nuclei/dalfox emit CWE, which the tool channel dropped: add optional `cwe?: string[]` to `ToolFinding` and thread it through the operator's finding materialisation. - flip `parserStatus: 'planned' → 'structured'` for httpx, dalfox, katana (nuclei/ffuf were already structured). Adds `src/__tests__/parsers.test.ts` + fixtures: per-scanner field mapping, the honesty contract (empty/garbled/adversarial → [], no throw), a factory-wiring check that a minted adapter returns findings while preserving raw stdout, and an end-to-end assertion that every parsed finding PASSES `gateLiveFinding` with provenance='tool'. The minted-adapter path is gated behind T3MP3ST_FULL_ARSENAL, so the benchmarked default arsenal is untouched. Supply-chain JSON tools (semgrep/gitleaks/trivy/grype) and secret scanners (need redaction) are a clean follow-up.
This commit is contained in:
1 parent
0f3213b310
commit
f8c283377c
11 files changed
+423
-4
No files matched your search
@@ -179,7 +179,7 @@ export const TOOL_ADAPTERS: ToolAdapter[] = [
|
||||
outputFormats: ['jsonl', 'text'],
|
||||
installHint: 'brew install projectdiscovery/tap/httpx',
|
||||
commandHint: 'httpx -u https://example.com -status-code -title -tech-detect -json',
|
||||
parserStatus: 'planned',
|
||||
parserStatus: 'structured',
|
||||
notes: 'HTTP probing and technology detection for discovered assets.',
|
||||
},
|
||||
{
|
||||
@@ -211,7 +211,7 @@ export const TOOL_ADAPTERS: ToolAdapter[] = [
|
||||
outputFormats: ['jsonl', 'text'],
|
||||
installHint: 'brew install projectdiscovery/tap/katana',
|
||||
commandHint: 'katana -u https://example.com -jsonl -silent',
|
||||
parserStatus: 'planned',
|
||||
parserStatus: 'structured',
|
||||
notes: 'Crawler for endpoint discovery and attack-surface mapping.',
|
||||
},
|
||||
{
|
||||
@@ -307,7 +307,7 @@ export const TOOL_ADAPTERS: ToolAdapter[] = [
|
||||
outputFormats: ['json', 'text'],
|
||||
installHint: 'brew install dalfox',
|
||||
commandHint: 'dalfox url https://example.com?q=test -o result.json --format json',
|
||||
parserStatus: 'planned',
|
||||
parserStatus: 'structured',
|
||||
notes: 'XSS validation adapter for scoped endpoints.',
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user