Files
bitgate/tests/security
thePR0M3TH3AN 7cc5756c15 fix(security): second-audit findings + restore cold CI
A second adversarial pass over areas the first audit did not reach: codecs,
transport internals, and the verify/outbox/private-mute paths added since.

Reliability/CI (most urgent)
- The previous commit's Node-safety base-class fallback lost the HTMLElement
  type, so defineElement() and this-typing broke. It only appeared with dist
  cleared, so it passed locally with stale declarations and would fail CI from
  a clean checkout. Annotated the fallback; cold lint/test/build now pass.

Security
- Relay URLs from a followed contact's kind:10002 flow straight to
  new WebSocket(url). normalizeRelayUrl only checked the ws(s) prefix, so a URL
  containing CR/LF or spaces passed through to the socket constructor — a
  CRLF-injection shape. Now validated with the URL constructor and rejected for
  any control character or whitespace, with a second guard at the socket
  boundary regardless of caller.
- canonicalStringify recursed without cycle detection: a self-referential value
  was a stack-overflow DoS rather than a wrong answer. Now guarded with a
  WeakSet; a repeat serializes as a sentinel.
- The viewer's private mute payload was JSON.parsed with no size bound. Capped
  at 128 KiB, checked before spending a decrypt on it.

What held up under this pass: address-coordinate parsing, the outbox per-author
relay cap (3), verifier handling of NaN/Infinity/string timestamps, and mute
tag robustness against non-string entries.

861 tests; audit clean; cold gates green.
2026-08-10 09:18:17 -04:00
..