CVE-2026-48599 Overview
CVE-2026-48599 is an authorization bypass vulnerability in the elixir-grpc/grpc library affecting versions 0.8.0 through versions prior to 1.0.0. The flaw resides in the HTTP-to-gRPC transcoding layer, where path bindings are merged with query and body parameters using incorrect precedence. Authenticated attackers can smuggle a conflicting value for any path-bound field through the query string or request body. Handlers that rely on path-bound fields for authorization, multi-tenancy scoping, or ownership checks are silently bypassed. The issue is categorized under CWE-639: Authorization Bypass Through User-Controlled Key.
Critical Impact
Authenticated attackers can access or modify resources belonging to other users by overriding path-bound identifiers such as user_id via query string or request body parameters.
Affected Products
- elixir-grpc grpc library version 0.8.0
- elixir-grpc grpc library versions after 0.8.0 and before 1.0.0
- Elixir applications using GRPC.Server.Transcode for HTTP-to-gRPC transcoding
Discovery Timeline
- 2026-06-15 - CVE-2026-48599 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2026-48599
Vulnerability Analysis
The vulnerability exists in Elixir.GRPC.Server.Transcode.map_request/5 defined in lib/grpc/server/transcode.ex. All three clauses of the function use Map.merge/2 with path_bindings as the first argument. In Elixir, Map.merge/2 gives the second argument precedence when keys collide, so path bindings carry the lowest precedence. Attacker-controlled query parameters or request body fields override values extracted by the router from the URL path. The decoded protobuf struct that reaches the handler contains attacker-supplied values for path-bound fields rather than the authenticated, router-extracted values.
Root Cause
The root cause is incorrect argument ordering in the Map.merge/2 call that combines path bindings with request parameters. Authorization checks downstream trust the path-bound field, but that field is no longer guaranteed to reflect the URL path component. This is a classic Insecure Direct Object Reference pattern arising from a parameter precedence flaw.
Attack Vector
An authenticated attacker issues a transcoded HTTP request such as GET /users/me/profile?user_id=victim. The router extracts me from the path, but the query string injects user_id=victim, which wins the merge. For routes configured with body: "*", a POST with {"user_id": "victim"} produces the same outcome. Any handler using the smuggled identifier for ownership validation will operate on the victim's resource.
) do
path_bindings = map_path_bindings(path_bindings)
query = Query.decode(query_string)
- request = Map.merge(path_bindings, query)
+ # Path bindings take precedence over query parameters
+ request = Map.merge(query, path_bindings)
Protobuf.JSON.from_decoded(request, req_mod)
end
Source: GitHub commit 33b6a09. The patch reverses the argument order so path bindings override query parameters, restoring the expected precedence.
Detection Methods for CVE-2026-48599
Indicators of Compromise
- HTTP requests where a query string or JSON body contains a field name that also appears as a URL path parameter (for example user_id, tenant_id, account_id).
- Application logs showing access to resources whose identifier does not match the authenticated principal's path-bound identifier.
- Successful resource reads or writes by a user against records owned by a different tenant.
Detection Strategies
- Inspect access logs for requests where path parameters and query or body fields share the same name with differing values.
- Audit handler code paths in transcoded gRPC services to confirm whether they use path-bound fields for authorization decisions.
- Correlate authenticated session identity against the resource identifier touched by each request and alert on mismatches.
Monitoring Recommendations
- Enable verbose request logging on the transcoding layer to capture both raw URL paths and decoded protobuf request structs.
- Track anomalous spikes in cross-tenant resource access attempts following deployments of vulnerable versions.
- Add unit and integration tests that assert path bindings cannot be overridden by query or body parameters.
How to Mitigate CVE-2026-48599
Immediate Actions Required
- Upgrade the elixir-grpc/grpc library to version 1.0.0 or later, which contains the precedence fix.
- Inventory all services using transcoded gRPC endpoints and identify handlers that trust path-bound fields for authorization.
- Review recent access logs for requests that supplied conflicting values for path-bound fields and investigate potentially affected accounts.
Patch Information
The fix is committed in elixir-grpc commit 33b6a09 and described in GHSA-mwr4-5g34-j5cq. Additional details are available in the Erlang Ecosystem Foundation CNA advisory and the OSV entry.
Workarounds
- Re-derive path-bound identifiers from the authenticated session or router context inside each handler instead of trusting the decoded protobuf struct.
- Add server-side authorization checks that compare the authenticated principal against the resource owner before any read or write operation.
- Reject requests where query or body parameters duplicate path-bound field names until the library upgrade is deployed.
# Update mix.exs dependency to a patched version
# {:grpc, "~> 1.0.0"}
mix deps.update grpc
mix deps.get
mix compile
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

