EEF-CVE-2026-71397: Unbounded request body accumulation on streaming RPCs causes memory exhaustion in grpc_server
Summary
Allocation of Resources Without Limits or Throttling vulnerability in elixir-grpc grpcserver allows unauthenticated attackers to exhaust memory and crash the node via an oversized client-streaming or bidirectional-streaming request body.
The streaming read clause of 'Elixir.GRPC.Server.Adapters.Cowboy.Handler':info/3 (grpcserver/lib/grpc/server/adapters/cowboy/handler.ex) never checks the configured maxbodysize. Only the unary read path enforces that cap. 'Elixir.GRPC.Server.Adapters.Cowboy':readingstream/1 (grpcserver/lib/grpc/server/adapters/cowboy.ex) appends every received chunk to its buffer until a complete length-prefixed message arrives. A client can declare a very large message and send it across many small HTTP/2 DATA frames, and the server buffers all of it.
This issue affects grpcserver: from 1.0.0 before 1.0.6.
Details
1. The cap applies to unary reads only
The commit that added maxbodysize checks it in readfullbody/4, which serves unary requests through the {:readfullbody, ref, pid} clause of 'Elixir.GRPC.Server.Adapters.Cowboy.Handler':info/3. The {:readbody, ref, pid} clause, which serves streaming requests, returns each chunk to the caller with no size check.
2. Unbounded buffering
'Elixir.GRPC.Server.Adapters.Cowboy':readingstream/1 reads chunks through that clause and appends each one to a binary buffer. It emits a message only when GRPC.Message.getmessage/1 finds a complete length-prefixed gRPC message in the buffer. Until then, the buffer grows with every chunk.
3. Memory exhaustion
A client that declares a large message length and keeps sending DATA frames without ENDSTREAM makes the buffer grow without limit. The BEAM eventually runs out of memory and the node crashes.
Proof of concept
1. Start a grpcserver endpoint that exposes a client-streaming or bidirectional-streaming RPC method. 2. Open an HTTP/2 connection and send a request to that method. 3. Send the request body across many small HTTP/2 DATA frames without ENDSTREAM, well past the configured maxbodysize. 4. Observe that the server buffers all of it and server memory grows. The equivalent unary call is rejected with RESOURCEEXHAUSTED.
Impact
An unauthenticated client can crash a grpcserver node through one streaming RPC connection. This takes down every service on that node.
Configurations
The server must expose at least one client-streaming or bidirectional-streaming RPC method.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
erlang/grpc_serverto a version that resolves this vulnerability.Fixed in 1.0.6 - Upgrade
Upgrade
grpc_serverto a version that resolves this vulnerability.Fixed in 1.0.6
Event History
Frequently Asked Questions
Which deployments are affected?
grpc_server versions from 1.0.0 up to, but not including, 1.0.6 are affected. The vulnerable behavior is specific to client-streaming and bidirectional-streaming RPC handling.
Does configuring max_body_size protect streaming RPCs?
No. In affected versions, max_body_size is enforced for unary reads but is not checked on the streaming read path.
What does an attacker need to do to trigger the issue?
An unauthenticated client can declare a very large length-prefixed message and deliver it in many small HTTP/2 DATA frames. The server accumulates the chunks until the complete message arrives, allowing memory exhaustion.
How can I determine whether my service is exposed?
Check whether it runs an affected grpc_server version and accepts client-streaming or bidirectional-streaming RPCs. Unary-only handling follows the body-size enforcement path described in the advisory.