Skip to content

Fuzz hardening: hostile YAML, the Windows path alphabet, loud corruption - #375

Merged
IanFrelinger merged 1 commit into
masterfrom
claude/gate-fuzz
Aug 23, 2026
Merged

Fuzz hardening: hostile YAML, the Windows path alphabet, loud corruption#375
IanFrelinger merged 1 commit into
masterfrom
claude/gate-fuzz

Conversation

@IanFrelinger

Copy link
Copy Markdown
Owner

Gold plan step 2 (sheet 10.2). Three hardenings, one invariant: hostile input gets a rejection with a reason — never a hang, an expansion blowup, an escaped exception, or a silently skipped record.

  • YamlGuard: anchors/aliases rejected pre-parse (billion-laughs class), 1MB cap. Honest prose ampersands survive.
  • Id allowlist replaces the blocklist, plus an explicit Win32 reserved-name deny on every OS. The suite caught its own author here: the first allowlist passed CON because it is perfectly alphanumeric.
  • Corruption fails loud: ListAsync used to silently skip null-deserialized records — a corrupt HELD record vanishing from the queue is an invisible pending decision. Reads now name the corrupt file and refuse.

37 new tests. Tests.Kernel 303/303 · cert gate 178 · kernel build 0/0.

🤖 Generated with Claude Code

…h alphabet, store corruption

Gold plan step 2. Three hardenings, each with the invariant that hostile input
produces a rejection WITH A REASON — never a hang, a blowup, an unhandled
exception, or a silently skipped record.

YamlGuard (both loaders, pre-parse):
  - anchors/aliases rejected outright. YamlDotNet expands aliases, so a tiny
    document can be crafted to expand exponentially (billion-laughs); ashlar
    documents never need aliases, so none are accepted. The scan is textual and
    deliberately a little eager; honest prose ampersands survive (tested).
  - 1MB size cap. Configuration, not cargo.

Proposal ids: ALLOWLIST replaces the blocklist. The old check blocked / \ . and
admitted the entire Windows hazard alphabet — trailing dots/spaces (Win32 strips
them, so two ids collide and append-once is bypassed), ':' (NTFS alternate data
streams), unicode confusables. Now: ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$ plus an
explicit Win32 reserved-name deny (CON/NUL/PRN/AUX/COM*/LPT*) on EVERY OS — a
store written on Linux with a CON.json breaks when it syncs to Windows, so the
same ids are legal everywhere. The reserved-name case was caught by this very
suite: the first allowlist passed CON because it is perfectly alphanumeric — the
fuzz tests corrected their own author before shipping.

Store corruption fails CLOSED and LOUD: ListAsync used to silently skip records
that deserialized to null and let JsonException escape raw. A corrupt HELD record
silently vanishing from the queue is an invisible pending decision — the worst
failure shape an admission store can have. Reads now surface a Corrupt-gate-record
error naming the file; a store that cannot be fully read is a store this class
refuses to summarize.

37 tests: alias bomb (rejected in <2s, before expansion), oversize, six
garbage/type-confusion shapes against both loaders with no escaping exceptions,
21 hostile ids, 4 legitimate ids, truncated and null records.

Verified: kernel build 0/0, Tests.Kernel 303/303, cert gate 178.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@IanFrelinger
IanFrelinger merged commit c97c09c into master Aug 23, 2026
6 checks passed
@IanFrelinger
IanFrelinger deleted the claude/gate-fuzz branch August 23, 2026 19:10
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.

2 participants