Skip to content

Fix ReDoS spawn-hang + prefix traversal bypass + verify-then-attest (132->193) - #11

Merged
madetocreate merged 2 commits into
mainfrom
oss-improve/coverage-and-hardening
Jun 21, 2026
Merged

Fix ReDoS spawn-hang + prefix traversal bypass + verify-then-attest (132->193)#11
madetocreate merged 2 commits into
mainfrom
oss-improve/coverage-and-hardening

Conversation

@madetocreate

Copy link
Copy Markdown
Contributor

What

Crypto path audited (Ed25519 sign/verify sound); fixed 4 real security issues in the sanitizer/attester.

  • ReDoS: a catastrophic-backtracking regex in a manifest froze the spawn hot path for 61s on a 40-char arg. New looksCatastrophic linear pre-check (fail-closed) + regex.maxLength cap. 61s -> <100ms.
  • Prefix path-traversal: /safe/../../etc/passwd passed a prefix:"/safe/" rule. New denyTraversal (default on, opt-out with false).
  • Control chars: VT/FF/NEL now in the forbidden set (CVE-2025-69256 fixtures).
  • attestSpawnVerified: verify-then-attest fail-safe (bare attestSpawn did not verify the signature).
  • +61 tests (each attack-blocked + benign-allowed; 17 safe regexes pass the ReDoS guard with zero FPs).

Tests 132 -> 193. Version -> 0.2.0 (behavior change: denyTraversal default on). No publish in this PR.

highrise441 and others added 2 commits June 21, 2026 15:00
Four security fixes to the default-deny argument sanitizer and spawn
attester, each with attack-blocked AND benign-allowed tests (+61 tests,
132 -> 193 total). All packages move to 0.2.0 in lockstep.

- ReDoS guard: evalArgRule refuses to run regex patterns prone to
  catastrophic backtracking (nested unbounded quantifiers like (a+)+).
  The pattern is author-signed but the value is attacker-controlled — a
  careless pattern previously froze the spawn hot path for 60+ seconds on
  a crafted arg. Detection is a linear-time scan (cannot itself ReDoS),
  fails closed. New regex `maxLength` cap (default 4096) as second layer.
  Exposed as looksCatastrophic().

- Prefix path-traversal guard: prefix rules rejected `..` was bypassable
  (/safe/../../etc/passwd satisfies prefix:"/safe/"). Now rejects `..`
  components incl. %2e%2e, POSIX+Windows separators, default-on via new
  `denyTraversal` field; enforced at eval time so it holds for in-memory
  manifests too. Exposed as containsTraversal().

- Control-char gap: shellSafeString now also blocks VT (U+000B),
  FF (U+000C), NEL (U+0085), completing the newline/separator deny set.
  CVE-2025-69256 replay fixtures extended.

- attestSpawnVerified(): verifies signature then attests in one fail-safe
  call, closing the footgun where an unverified/tampered manifest reaches
  attestSpawn.

Docs: README security model + quickstart, MANIFEST-FORMAT arg-rule table
+ ReDoS note, THREAT-MODEL mitigation rows, CHANGELOG 0.2.0.

Build + typecheck + full suite green. No runtime-dep changes (lib still
zod-only). Behaviour change: prefix denyTraversal defaults true (opt-out
with denyTraversal:false).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…and-hardening

# Conflicts:
#	package-lock.json
#	packages/demo-server/package.json
@madetocreate
madetocreate merged commit 9c1c24d into main Jun 21, 2026
3 checks passed
@madetocreate
madetocreate deleted the oss-improve/coverage-and-hardening branch June 21, 2026 16:38
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