Skip to content

test(feed-engine): parser robustness / fuzz suite + regexExtract guard#164

Merged
rinjanianalytics merged 1 commit into
masterfrom
test/feed-engine-fuzz
Jun 17, 2026
Merged

test(feed-engine): parser robustness / fuzz suite + regexExtract guard#164
rinjanianalytics merged 1 commit into
masterfrom
test/feed-engine-fuzz

Conversation

@rinjanianalytics

Copy link
Copy Markdown
Owner

Second cross-cutting hardening item. The declarative feed-engine is the parse seam for untrusted upstream feed bytes (ThreatFox, CISA, OpenPhish today; the template every new feed follows). This locks its hostile-input contract.

Suite (353 generated cases, ~0.5s, no infra)

  • extractRecords (text/csv) never throws on any bytes — empty, binary, unicode, 200 KB, unterminated quotes, ragged rows, comment-only.
  • applyTransforms is now TOTAL — no op throws on any input (14 ops × 22 hostile inputs + a 200-iteration random-chain fuzz).
  • runEngine isolates bad records — good rows → records, bad → errors, invariant read === ok + failed; a malformed payload throws for the caller (engineHandler) to catch as a feed failure.
  • getPath never throws, and a malicious __proto__ CSV header can't pollute Object.prototype (verified).

One fix

regexExtract now guards new RegExp(pattern) (try/catch → undefined) so a malformed manifest pattern yields "no match" instead of throwing — making applyTransforms a total function. Previously a bad pattern threw (caught per-record by runEngine, but every record using it would fail).

Parity suites unaffected — 381 engine tests green, gateway tsc clean.

The engine is the parse seam for untrusted upstream feed bytes. This locks its
hostile-input contract (353 generated cases, ~0.5s, no infra):
- extractRecords (text/csv) never throws on any bytes (empty, binary, unicode,
  200KB, unterminated quotes, ragged rows).
- applyTransforms is now TOTAL — no op throws on any input (14 ops × 22 inputs).
- runEngine isolates bad records: good rows in `records`, bad in `errors`,
  invariant read === ok + failed; a malformed payload throws for the caller.
- getPath never throws; a malicious `__proto__` CSV header can't pollute
  Object.prototype (verified).

Fix: regexExtract guards `new RegExp(pattern)` (try/catch → undefined) so a
malformed manifest pattern yields "no match" instead of throwing — makes
applyTransforms total. Parity suites unaffected (381 engine tests green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rinjanianalytics rinjanianalytics merged commit 3cd5338 into master Jun 17, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant