ReviewOS

zig-utils/zig-js

Enumeration: securely seed transient string membership indexes

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

Parents: #493, #495 Related: #491, #758

Problem

Three enumeration paths still place attacker-controlled property names in default-seeded native string maps: for-in prototype-chain shadowing, JavaScriptCore-shaped C API property-name snapshots, and host-class own-key merging. Predictable placement permits precomputed collision-heavy key graphs. Ordinary object own-key enumeration also pays for a membership table even when no host hook can introduce duplicates.

Scope

  • Reuse one exact-byte, lazy, failure-atomic secure membership helper for transient enumeration indexes.
  • Secure for-in visited names and C API property-name snapshot visited names with one per-enumeration seed.
  • Allocate host/ordinary own-key merge membership only after a host hook contributes its first string key; ordinary objects without host string keys must avoid the table and entropy request entirely.
  • Preserve integer/string/Symbol ordering, prototype shadowing by non-enumerables, deletion rechecks, Proxy/module/host callback observation, encoded NUL keys, adversarial-width names, moving-GC lifetimes, and OOM behavior.

No-workaround rules

  • No property/depth cap, input blacklist, deterministic fallback seed, hash-only equality, skipped prototype/invariant/host keys, reordered callbacks, or reduced enumeration semantics.
  • No stack, queue, job, Promise, Worker, or Map/Set iterator implementation changes.

Acceptance

  • All three transient string indexes use non-default per-enumeration secure contexts.
  • Ordinary no-host own-key enumeration avoids membership allocation and entropy.
  • Wide/NUL/prototype-shadowing/host-overlap/Proxy cases retain exact order and errors across tree-walker and required VM paths.
  • Focused normal and TSan tests pass without leaks or races.
  • Exact-parent relevant Test262 inventories have zero regressions.

Implemented by 1adc7b7b.

Evidence: focused native tier/C-API tests 2/2; complete for-in unit filter 6/6; focused TSan tier/C-API/Proxy/helper tests 4/4, all with zero failures/leaks/races. Exact-parent Test262 remains test/language/statements/for-in 115 pass / 0 fail, test/built-ins/Reflect/ownKeys 13 / 0, and test/built-ins/Proxy/ownKeys 27 / 0 (0 flips, 0 regressions).

9 days ago

Completed on main by 1adc7b7b. Transient enumeration now shares one lazy secure exact-byte membership helper, ordinary no-host own-key enumeration skips the table, and host overlap/tree-walker/required-VM behavior is covered without caps, fallback seeds, or semantic shortcuts.

9 days ago

Follow-up #760 landed in 52a7c387, reusing the lazy secure exact-byte membership helper for Annex B legacy function names without changing ordinary enumeration or the lexical NameStack. Annex B Test262 remains 845 pass / 0 fail.

9 days ago

Follow-up #762 closed the remaining public host-class/private ABI property-name membership gap in 837a6b62, reusing the same lazy exact-byte hardening contract and removing one redundant post-ownKeys table.

9 days ago

Follow-up #763 generalized #762’s lazy secure exact-byte map to long-lived private ABI borrowed views and snapshot string tables in fix(private-abi): seed borrowed string interning (#763). Exact-parent enumeration remains 155/155 with 0 flips.

Sign in to comment on this issue.