Vulnerability EEF-CVE-2026-124278
Summary
Path bindings ignored for gRPC Content-Types on transcoded routes in elixir-grpc grpc_server
Details
Summary
Authorization Bypass Through User-Controlled Key vulnerability in elixir-grpc grpc_server and grpc allows an attacker to make a handler act on a resource other than the one named in the URL of an HTTP-transcoded route, via a request with a gRPC Content-Type.
Only the transcoding clause of GRPC.Server.do_handle_request/4 (grpc_server/lib/grpc/server.ex, and lib/grpc/server.ex before the package split) applies the route's path bindings to the request message. The Cowboy handler picks that clause from the request Content-Type, not from the route. A request to a transcoded URL with application/grpc or application/grpc-web is decoded from the body alone, so every path-bound field takes its value from the body. A gateway, proxy rule or WAF that authorizes on the URL path sees one resource while the handler receives another.
This issue affects grpc_server: from 1.0.0 before 1.1.0; grpc: from 0.8.0 before 1.0.0.
Details
1. The header selects the clause
The Cowboy handler derives the access mode from the request Content-Type. application/json selects :http_transcoding, application/grpc selects :grpc and application/grpc-web+proto selects :grpcweb. The router still matches the transcoded URL template and extracts its path bindings.
2. Bindings are applied in one clause only
GRPC.Server.do_handle_request/4 reads the bindings with adapter.get_bindings/1 and merges them through GRPC.Server.Transcode.map_request/5 only in the :http_transcoding clause. The unary and request-streaming clauses decode the body alone with the selected codec. GRPC.Codec.Proto is in the default codecs of every server, so application/grpc is always accepted.
3. The HTTP/1.1 guard never matches
resolve_access_mode/3 has a clause that forces transcoding for HTTP/1.1 requests. It matches the version as the binary "HTTP/1.1", while Cowboy stores the version as an atom, so the clause never applies and the request works over plain HTTP/1.1.
4. Result
A request to /v1/messages/alice with Content-Type: application/grpc and a message that sets name to victim reaches the handler with name set to victim. With an empty message the field is empty: the path binding is never consulted.
Proof of concept
- Start a server with
http_transcode: trueand a transcoded route that binds a field from the path, for exampleGET /v1/messages/{name}. - Build a gRPC frame whose message sets
nametovictim. - Send it over HTTP/1.1 as
GET /v1/messages/alicewithContent-Type: application/grpc. - Observe that the handler receives
nameset tovictim, notalice.
Impact
An attacker whose requests are authorized by URL path can make the handler read or modify a resource the path does not name, such as another tenant's data.
Configurations
HTTP-to-gRPC transcoding must be enabled with http_transcode: true. Access to a resource must be decided from the URL path rather than from the decoded request, for example by an API gateway, proxy rule or WAF in front of the server.
Related Vulnerabilities
Other vulnerabilities affecting the same packages