Files
zeekayandGitHub f02db2dc95 fix(cors): anchor origin regexes + gate credentials on origin-allow (#12)
Credentialed-CORS hardening. Two independent bugs in the CORS header
middleware let a credentialed response reach a foreign origin.

header.go:
- anchorOriginRegex wraps every AccessControlAllowOriginListRegex pattern in
  ^(?:…)$ so the shipped `https://([a-z0-9-]+\.)?hanzo\.ai` can no longer
  substring-match the attacker origin `https://hanzo.ai.evil.com`.
  regexp.MatchString is unanchored, so the pattern reflected any origin that
  merely prefixed the brand. The (?:…) group keeps top-level alternation
  intact; pre-existing anchors are stripped so the result never double-anchors.
- Access-Control-Allow-Credentials is now emitted ONLY alongside a matched
  Access-Control-Allow-Origin — on both the response path
  (PostRequestModifyResponseHeaders) and the preflight path
  (processCorsHeaders). It was set unconditionally, so ACAC:true could pair
  with a reflected/foreign origin set by another layer (backend or CDN) — the
  near-account-takeover class.

zap_backend.go (INGRESS_ZAP_BACKENDS inert by default; pre-enable hardening):
- Cap the buffered request body (io.LimitReader; default 64 MiB, override
  INGRESS_ZAP_MAX_BODY_BYTES). Unbounded io.ReadAll let one oversized request
  OOM the ingress.
- Honour req.Context() cancellation before dialing.
- Correct the false "PQ-secure" doc: v0.1.0 dials plaintext TCP; note the
  absent request-write deadline.

Tests: anchored-regex + credential-gating regressions (attacker suffix, null
origin, allowlisted subdomain) on both response and preflight paths; body-cap
and parseMaxBody unit tests.
2026-07-03 16:47:31 -07:00
..