Files
vm/docs/rfcs
harshdoesdev 6c4e3a7b7c feat(proxy): scope secret substitution to the request head
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.
2026-08-05 05:52:32 +05:30
..