ReviewOS

zig-utils/zig-js

JSON.parse: securely seed reviver metadata indexes

#755
Closed chris opened this 9 days ago ·
9 days ago

Parent: #493 Related: #473, #662

Problem

When JSON.parse receives a reviver, the parser records source metadata for object children in std.StringHashMapUnmanaged. Its default string context uses a process-predictable hash seed even though every indexed property name is attacker-controlled input. This leaves the reviver metadata side table as an avoidable algorithmic-complexity target after runtime collection and Shape tables were securely seeded.

Scope

  • Replace only the JSON parse-record object-property index with an exact-byte custom hash context.
  • Lazily draw one secure per-parse seed when the first tracked object property is indexed; scalar, no-reviver, array-only, and empty-object paths must not pay for a table or entropy request.
  • Reuse the interpreter-owned cryptographic seed stream and fail closed if initial secure entropy is unavailable.
  • Preserve duplicate-key last-record semantics, source context values, property ordering, reviver callback order, moving-GC lifetimes, and OOM failure atomicity.

No-workaround rules

  • No input blacklist, property-count/depth reduction, deterministic fallback seed, hash-only equality, skipped source metadata, or reordered callback.
  • Exact key bytes remain authoritative under every collision.

Acceptance

  • Tracked object-property indexes use a non-default per-parse secure hash context.
  • Empty/scalar/no-reviver paths remain lazy and allocate no metadata hash table.
  • Duplicate, escaped, NUL-bearing, integer-like, and adversarial-width keys retain exact reviver source/order semantics.
  • Focused normal and TSan tests pass without leaks or races.
  • Exact-parent JSON Test262 inventory has zero regressions.

Implemented by a06685ff.

Evidence: JSON units 15/15 with zero leaks; focused normal native test 1/1; focused TSan native and end-to-end tests 2/2 with zero races; exact-parent test/built-ins/JSON remains 165 pass, 0 fail (0 flips, 0 regressions).

9 days ago

Completed on main by a06685ff. The implementation uses one lazy secure seed per tracked parse, exact-byte equality, and failure-atomic context publication; no deterministic fallback or semantic workaround was added.

Sign in to comment on this issue.