Commit Graph
2 Commits
Author SHA1 Message Date
Hermes 9322831f1b fix(security): quoted local-part email mask — strip delimiter quotes, split on last @ (DC-109) [glm-grade=A]
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
2026-08-23 07:28:10 -07:00
Hermes 83ef84d218 feat(logging): central email PII masking across all log sinks [glm-grade=A]
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
DC-095: mask email addresses at every logger output choke point so raw
PII never reaches stdout/stderr, error.log, or audit-log.json regardless
of what a call site interpolates — msg strings, data payloads, error
messages/stacks, audit details, and error.log request lines (path/UA).

- Masked shape sa****@domain matches AuthProvider.maskEmail (UI-consistent)
- Bounded-quantifier regex: local {1,64} (incl. quoted local-parts),
  domain {0,253}, TLD {2,24} — adversarial 40KB string 3.3s -> 17ms,
  hostnames/versions/docker-refs untouched, idempotent under re-mask
- memo-Map recursion: DAG shared references get the same masked clone
  (WeakSet seen-guard leaked the raw original on 2nd reference); cycles
  resolve to in-progress clone
- Non-plain objects with own enumerable props cloned proto-preserving
  (Object.create) so class-instance email fields are masked; Date/RegExp
  pass through
- sanitize(): audit details mask email substrings in non-sensitive keys
  (invite/auth POST bodies no longer land raw in audit-log.json)
- 18-test suite covers sinks + adversarial judge findings (ReDoS timing,
  DAG, quoted locals, instances, request-line path/UA)

Judge: GLM-5.3 cold-read stand-in (Codex quota-dead until 2026-08-24,
substitution authorized by Sami 2026-08-17). Rounds C -> C -> A.
Verdict: urn:ump:zorj7vcrnw2t2jhhcp2g6wz4simvhyjdqwu2mjsifxlkzb2dwjmq
Suite: 117 suites / 2724 tests green.
2026-08-22 20:49:09 -07:00