Security: stop the API mux honouring X-HTTP-Method-Override (CVE-2026-37236) - #3960
Open
rossnelson wants to merge 1 commit into
Open
rossnelson wants to merge 1 commit into
rossnelson wants to merge 1 commit into
Conversation
CVE-2026-37236 (9.8). grpc-gateway's ServeMux honours the X-HTTP-Method-Override header on a POST sent as application/x-www-form-urlencoded, rewriting the method before it routes. Anything in front of this that allows or denies by method — a proxy, a WAF — is then deciding on a method the mux discards, so a POST that layer permits can arrive here as a DELETE. The upstream fix is opt-in. It landed in v2.29.0 and the default is unchanged even on the newest release, so bumping the dependency satisfies a scanner and changes nothing on its own. Both halves are here: the bump to v2.30.0, and the option that actually removes the behaviour. The test asserts the behaviour rather than the version, because the version is the part that does not fix it. It records which gRPC method a request reaches, since status codes cannot show that — every unimplemented method answers alike, so a request routed to the wrong RPC is indistinguishable from one routed to the right one. Against the schedules path, a POST carrying `X-HTTP-Method-Override: DELETE` must still reach CreateSchedule; without the option it reaches DeleteSchedule, which is the whole of the vulnerability in one assertion. Only grpc-gateway and two genproto indirects move; nothing else is pulled in. google.golang.org/grpc is already past CVE-2026-84445, which was the other advisory reported alongside this one.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3955.
Description & motivation 💭
CVE-2026-37236 (9.8).
grpc-gateway'sruntime.ServeMuxhonours theX-HTTP-Method-Overrideheader on aPOSTsent asapplication/x-www-form-urlencoded, rewriting the method before it routes.Anything in front of this that allows or denies by method — a proxy, a WAF — is then deciding on a method the mux goes on to discard. A
POSTthat layer permits can arrive here as aDELETE.Bumping the dependency does not fix it
This is the part worth pausing on. The upstream fix landed in v2.29.0, but it is opt-in — the default behaviour is unchanged even on the newest release. Bumping alone clears the scanner and changes nothing.
So this is both halves:
grpc-ecosystem/grpc-gateway/v2→ v2.30.0runtime.WithDisableHTTPMethodOverride()on the API mux inserver/server/api/handler.goDesign Considerations 🎨
runtime.NewServeMuxhas a single call site, so there is no second surface to protect.grpc-gatewayand twogenprotoindirects move; nothing else is pulled in.google.golang.org/grpcis at v1.83.2, past the v1.82.2 fix for CVE-2026-84445, which was reported alongside this one.POSTwith a form content type falling through to a matchingGEThandler) is upstream behaviour this option deliberately leaves alone. It does not let a request reach a different RPC than its method allows, so it is not part of this CVE — but it did shape the test, see below.Testing 🧪
How was this tested 👻
server/suite passesTestMuxIgnoresHTTPMethodOverrideasserts the behaviour, not the version — the version is precisely the part that does not fix it.It records which gRPC method a request actually reaches, because status codes cannot show this: every unimplemented method answers alike, so a request routed to the wrong RPC is indistinguishable from one routed to the right one. My first two attempts at a status-code assertion both passed against the vulnerable build.
The schedules path routes three methods to three different RPCs, which makes the routing decision unambiguous:
POSTCreateScheduleDELETEDeleteSchedulePOST+X-HTTP-Method-Override: DELETECreateScheduleConfirmed it catches the vulnerability — with the option removed:
That is the vulnerability in one assertion: a create becomes a delete.
Full suite passes (the only failure,
server/ui/embed.go, is the pre-existing "needs a built UI" setup error that CI resolves by building the UI first).Checklists
Merge Checklist