carlos / platform Public

Edge: hop header cleanup misses empty and empty-first values (X-Carlos-Hop, X-Carlos-Hop-Auth) open

Found while building the #358 rate limit (branch design-edge-rate-limit-358, Task 6). Not fixed there: it predates that work and is outside its scope.

acceptHop (internal/edge/homemap.go) promises that hop vocabulary is "deleted in ALL hop cases" so a tenant app that reflects headers cannot launder it. Two gaps on the no-marker path:

  1. The stray-signature cleanup guards with r.Header.Get(hopAuthHeader) != "". Get returns the first value, so an inbound X-Carlos-Hop-Auth: "" or ["", "anything"] skips the Del and reaches the app.
  2. X-Carlos-Hop: ["", "1"] reads as "no hop" (Get is empty) and that path never deletes X-Carlos-Hop, so both values reach the app.

Neither grants anything (a hop still has to verify), so this is hygiene, not an auth bypass. The fix is the one Task 6 applied to the new X-Carlos-Hop-Door header: delete unconditionally before deciding, and accept a value only when there is exactly one.

The #358 branch's TestAcceptHopSetsDoorMark has the case table to copy.