CVE-2026-123635: Refused calls drain the HTTP/2 connection flow-control window in elixir-grpc grpc_server

Published Nov 13, 2026
·
Updated

Summary

Missing Release of Resource after Effective Lifetime vulnerability in elixir-grpc grpcserver allows a client to stall all later calls on a shared HTTP/2 connection via calls that the server refuses while their DATA frames are in flight.

The stream handler grpcstreamh (grpcserver/src/grpcstreamh.erl) requests flow from Cowboy only for request data that has arrived. When the server refuses a call early, for example because the body exceeds maxbodysize or the method is not implemented, Cowboy drops the DATA frames still in flight for that stream. Their bytes are not returned to the connection flow-control window. After enough refused calls the window is empty. No call on that connection can then send a request body, and each call waits until its deadline. Other connections are not affected.

This issue affects grpcserver: from 1.0.0 before 1.1.0.

Details

1. Flow is requested only for data that arrived

Cowboy increases the HTTP/2 connection window only when a stream handler returns a {flow, N} command. grpcstreamh returns that command only for request data it has received.

2. A refused call leaves data uncredited

When the server refuses a call, the stream stops. The client can still have DATA frames in flight for it. Cowboy drops those frames without running the handler, so no flow is requested for their bytes and no connection-level WINDOWUPDATE is sent.

3. The window empties

Each refused call with DATA in flight reduces the connection window for good. With the default 65,535-byte window, the window was empty after two refused calls in a test against v1.0.6. An empty window stops all request data, so no handler requests flow again and the window stays empty.

4. Result

Every later call on the connection that has a request body waits until its deadline. A new connection works normally.

Proof of concept

1. Start a gRPC server with a small maxbodysize, for example 1000 bytes. 2. Open one HTTP/2 connection with a client that tracks the connection window. 3. Send a unary call with a body above the limit and wait for the RESOURCEEXHAUSTED reply. 4. Send more DATA frames on the refused stream, up to what the stream and connection windows allow. 5. Repeat steps 3 and 4 on new streams until the connection window is 0. 6. Send a small valid unary call on the same connection. Observe that its body cannot be sent and that the call ends at its deadline.

Impact

A client whose calls share an HTTP/2 connection with other callers can make all later calls on that connection wait until their deadlines. Calls on other connections are served normally.

Workarounds

Put a Cowboy stream handler in front of grpcstreamh with the adapter option streamhandlers: [MyHandler, :grpcstreamh]. In init/3, the handler calls :cowboystream.init/3 and adds a {:flow, size} command when the request has a body, where size is Cowboy's maxframesizereceived (16384 by default). It passes all other callbacks to :cowboystream.

Configurations

Calls from more than one caller must share one HTTP/2 connection to the server, for example through a proxy or a shared client channel.

Other sources

Missing Release of Resource after Effective Lifetime vulnerability in elixir-grpc grpcserver allows a client to stall all later calls on a shared HTTP/2 connection via calls that the server refuses while their DATA frames are in flight.

The stream handler grpcstreamh (grpcserver/src/grpcstreamh.erl) requests flow from Cowboy only for request data that has arrived. When the server refuses a call early, for example because the body exceeds maxbodysize or the method is not implemented, Cowboy drops the DATA frames still in flight for that stream. Their bytes are not returned to the connection flow-control window. After enough refused calls the window is empty. No call on that connection can then send a request body, and each call waits until its deadline. Other connections are not affected.

This issue affects grpcserver: from 1.0.0 before 1.1.0.

— MITRE

Affected Software

1 affected componentFixes available
erlang/grpc_server>=1.0.0<1.1.0
1.1.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade erlang/grpc_server to a version that resolves this vulnerability.

    Fixed in 1.1.0
  2. Upgrade

    Upgrade grpc_server to a version that resolves this vulnerability.

    Fixed in 1.1.0

Event History

Nov 13, 2026
CVE Published
via MITRE·03:40 PM
Data Sourced
via MITRE·03:40 PM
DescriptionWeakness
Data Sourced
via OSV·03:40 PM
DescriptionSeverityWeaknessAffected Software
Data Sourced
via NVD·04:17 PM
DescriptionSeverityWeakness

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203