mirror of
https://github.com/hanzoai/vm.git
synced 2026-10-01 00:47:56 +00:00
Substitution was a blind byte replace over the whole guest to upstream stream, which failed two ways. A placeholder straddling two reads went upstream unsubstituted, reproduced on an 80KB upload where 3 of 2000 leaked. And substituting in a body changed its length while leaving the framing that declared it, so any request carrying a secret in its body hung or was closed. Measured across framings: with a secret the same length as the placeholder every shape returned 200, and with a differing length only the header case did. Since placeholders are a fixed 30 bytes and no real credential is 30 bytes, body substitution has never worked for anyone, and no comparable sandbox proxy offers it. Substitution now applies to the request line and any header value, scoped by position rather than by a list of header names, so an unknown vendor header works with no configuration and a credential in a query parameter is covered. Bodies stream through untouched, so no declared length is ever invalidated. This is deterministic rather than timed. An unterminated head is unambiguously an unfinished request, where an arbitrary byte offset is not, so no flush heuristic is needed at any throughput. Framing is read but never rewritten, only to find where the next head begins on a reused connection. Anything RFC 9112 6.3 flags as a possible smuggling attempt, both Content-Length and Transfer-Encoding, conflicting lengths, an unparseable head, CONNECT or Upgrade, stops substitution and degrades to a byte tunnel. An intermediary that never re-frames cannot desynchronise its upstream by re-framing wrongly. Also cheaper than before: only heads are scanned, not every byte of every body. A live relay additionally re-resolves its secrets every 5s, so a rotation reaches a connection that is already open instead of waiting for it to reconnect. RFC 0002 is rewritten to match, and records the evidence, the rejected options, and a separate defect found on the way: substitution is one directional, so an upstream that reflects a request returns the real credential to the guest. Verified end to end on real VMs: header substitution with a length-changing secret, an unknown custom header, a 40KB POST body forwarded untouched, five requests substituted on one reused connection, a placeholder in a body carried through verbatim with a 200 instead of a hang, and no placeholder leaked in any case.