Rate-limit key collapses every peer with an empty RemoteAddr into one bucket #168
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Raised by the independent review of #162 and left out of scope there, since it predates that change and is not what the change touches.
clientKeyininternal/middleware/ratelimit.goparsesipFromHostPort(r.RemoteAddr);ipFromHostPortreturns""whennet.SplitHostPortfails, the parse then fails, and the fallback returnsr.RemoteAddrraw. For an emptyRemoteAddrthat raw value is"", so every such peer keys on the same empty string and shares one rate-limit bucket across all four limiter instances.Severity is low. It is fail-closed — peers collapse into one bucket rather than each minting their own — and
net/httpalways populatesRemoteAddrfor a TCP listener, so it is not reachable in the normal serving path. It is reachable for a hand-built*http.Request, and the same collapse is the documented behaviour for a Unix-socket listener, where every peer legitimately carries the sameRemoteAddr.Worth deciding rather than leaving silent, because the empty case is currently indistinguishable from the Unix-socket case in the code and is untested either way.
Options
RemoteAddris empty, on the grounds that a request with no peer identity cannot be rate limited at all.Done-criteria once decided
RemoteAddrpath has a test asserting whichever behaviour is chosen.clientKeydistinguishes the empty case from the Unix-socket case.