Jul 22, 2026·8 min read·6 visits
gRPC-Go is vulnerable to a denial-of-service bypass due to incomplete HTTP/2 Rapid Reset mitigation, alongside xDS RBAC parsing flaws that cause application panics or silent authorization bypasses.
GHSA-HRXH-6V49-42GF is a critical security advisory addressing two distinct vulnerabilities within gRPC-Go: an HTTP/2 Control Buffer Flooding weakness that allows unauthenticated denial of service, and xDS Role-Based Access Control parser weaknesses that lead to authorization bypasses and application panics.
gRPC-Go is the Go implementation of gRPC, a widely used, high-performance remote procedure call (RPC) framework. It plays a critical role in cloud-native application architectures, service meshes, and microservices environments, serving as the communication backbone for highly distributed systems. The security advisory GHSA-HRXH-6V49-42GF addresses two separate classes of vulnerabilities within gRPC-Go: an HTTP/2 Control Buffer Flooding weakness and xDS Role-Based Access Control (RBAC) parser vulnerabilities.
The HTTP/2 vulnerability represents an incomplete mitigation against the HTTP/2 Rapid Reset attack vector (originally tracked under CVE-2023-44487). While previous mitigations implemented queue throttling for specific transport response frames, this bypass allowed malicious clients to saturate the server control buffer with unthrottled frames. An unauthenticated attacker can exploit this issue to exhaust memory and CPU resources, causing a denial-of-service condition on the target container or host.
The second vulnerability resides in the xDS RBAC engine, which parses authorization policies. Due to parser omissions, the engine did not support specific field types, lacked default fallback handling in type switches, and misaligned with gRPC RFC A41 specifications. These parsing weaknesses could cause application panics or silent failures in enforcing authorization controls, allowing unauthorized entities to bypass access policies.
Combined, these vulnerabilities expose critical gRPC infrastructure to both availability threats and security boundary compromises. Security teams must evaluate their external and internal gRPC endpoints to determine their susceptibility to these attack surfaces.
To understand the HTTP/2 control buffer flooding vulnerability, it is necessary to examine how gRPC-Go coordinates frame transmission. The transport layer relies on an internal queue structure called controlBuffer (located in internal/transport/controlbuf.go) to manage control frames and scheduled tasks. To prevent denial-of-service attacks from malicious or misbehaving clients, the controlBuffer enforces a strict threshold on queued transport response frames.
Previously, this threshold was capped at 50 queued transport response frames, represented by the constant maxQueuedTransportResponseFrames. The buffer verified whether an incoming frame should count toward this limit by calling isTransportResponseFrame() on each queued item. Only a limited subset of frames, such as settings acknowledgments and certain server-initiated reset frames, returned true for this check.
An attacker exploiting this logic can issue a continuous stream of HEADERS frames immediately followed by RST_STREAM frames. This sequence generates internal control buffer items like registerStream, earlyAbortStream, and non-reset cleanupStream frames. Because these specific internal items returned false under the isTransportResponseFrame() interface, they bypassed the queue limit entirely, accumulating in memory without triggering the throttle.
Regarding the xDS RBAC parsing flaw in internal/xds/rbac/matchers.go, the root cause is a lack of defensive error handling in the configuration parsing logic. The parser used a Go type-switch over protobuf messages to convert xDS policies into internal matchers. Because the type switch lacked default branches for unsupported configurations or nested rules (such as NotRule or NotId permissions), encountering unexpected or deprecated structures resulted in configuration failures or severe application-level panics.
The official fix resolved the control buffer flooding vulnerability by replacing the specific isTransportResponseFrame() check with a generic isThrottled() interface. This new interface applies to almost all structures within the control buffer, ensuring that virtually all control items contribute to the queue limit. The default limit has been increased to 100 and is now fully configurable via an environment variable.
Below is the patch implemented in internal/transport/controlbuf.go to enforce the new throttle mechanism:
// The patch replaces the specific response frame check with a broader throttle
-type cbItem interface {
- isTransportResponseFrame() bool
-}
+type cbItem interface {
+ isThrottled() bool
+}
+
+// ThrottledItem is embedded in control buffer structures to enforce queue limits
+type throttledItem struct{}
+
+func (throttledItem) isThrottled() bool { return true }This throttledItem struct is now embedded within almost all control buffer elements, including registerStream, earlyAbortStream, cleanupStream, and window update frames. The only items exempted from throttling are clientHeaders, serverHeaders, and dataFrame elements, which are managed by separate flow control mechanisms.
In internal/xds/rbac/matchers.go, the patch adds strict type assertion fallbacks and maps the deprecated source_ip identifier to direct_remote_ip in accordance with gRPC RFC A41:
case *v3rbacpb.Principal_SourceIp:
- // The source ip principal identifier is deprecated. Thus, a
- // principal typed as a source ip in the identifier will be a no-op.
- // The config should use DirectRemoteIp instead.
+ // The source ip principal identifier is deprecated, but gRPC RBAC
+ treats it as equivalent to direct_remote_ip as per A41.
+ m, err := newRemoteIPMatcher(principal.GetSourceIp())
+ if err != nil {
+ return nil, err
+ }
+ matchers = append(matchers, m)Additionally, a default branch was introduced to return a descriptive parsing error instead of allowing unsupported configurations to trigger failures or panics:
case *v3rbacpb.Permission_RequestedServerName:
- // Not supported in gRPC RBAC currently - a permission typed as
- // requested server name in the initial config will be a no-op.
+ m, err := newRequestedServerNameMatcher(permission.GetRequestedServerName())
+ if err != nil {
+ return nil, err
+ }
+ matchers = append(matchers, m)
+ default:
+ return nil, fmt.Errorf("unsupported permission rule type: %T", p)This implementation closes the bypass vector entirely. By explicitly defining behavior for unsupported fields and handling unknown types safely, the RBAC engine prevents configuration-driven denial of service and enforces authorization invariants.
To exploit the control buffer vulnerability, an attacker must establish a direct TCP connection to the target gRPC-Go server. The exploit does not require valid application-level credentials because the vulnerability is triggered at the HTTP/2 framing layer before gRPC-level authentication or authorization checks are performed. The attack vector relies on sending rapid, multiplexed frame streams over a single connection.
An attacker constructs a specialized HTTP/2 client that continuously opens and terminates streams. Specifically, the client transmits an HTTP/2 HEADERS frame to initiate a stream, immediately followed by an HTTP/2 RST_STREAM frame to cancel it. The attacker repeats this sequence thousands of times in rapid succession. The server processes each stream open and close request, generating internal control tasks.
Because these internal tasks bypass the isTransportResponseFrame() check, the controlBuffer queues them without applying any rate limiting or backpressure on the connection. The transport reader continues reading frames from the socket, allocating memory for each new queue item. This unchecked buffer growth rapidly consumes host memory, eventually triggering the system Out-Of-Memory (OOM) killer or degrading performance to the point of complete unavailability.
Exploitation of the xDS RBAC parser requires the ability to inject or modify configurations distributed to the gRPC client or server via the xDS control plane. This is typical in a compromised or multi-tenant service mesh environment. By supplying an RBAC policy containing unsupported, deprecated, or malformed fields, an adversary can cause the gRPC application to crash during initialization or fail back to an insecure state that permits unauthorized requests.
The primary impact of the HTTP/2 control buffer flooding vulnerability is a complete denial of service. Since gRPC-Go is widely used in high-throughput microservices, edge proxies, and API gateways, a denial of service on a core gRPC server can disrupt upstream and downstream dependencies. The vulnerability allows an external, unauthenticated attacker to take down critical endpoints with minimal network bandwidth.
The second impact relates to authorization bypass and application instability. An xDS RBAC parser panic can crash gRPC-Go services when applying new security configurations, leading to operational downtime. In cases where the parser ignores unsupported configurations or deprecated fields like source_ip (instead of evaluating them strictly), access control policies can fail silently, exposing internal RPC methods to unauthorized network clients.
These issues are classified with a CVSS v3.1 base score of 8.6, reflecting high severity due to the unauthenticated nature of the denial-of-service vector and the potential for security policy bypasses. The EPSS score and KEV status should be monitored, as the underlying HTTP/2 Rapid Reset concept is well understood and actively used in automated exploit toolkits.
Remediation of these vulnerabilities requires upgrading the grpc-go dependency to version v1.82.1 or later. This release incorporates the updated throttling logic, the broader isThrottled interface check, and strict error handling within the RBAC parser. Projects managing dependencies via Go modules should update their go.mod files and rebuild their applications.
For deployments where immediate upgrading is not feasible, operators can configure the environment variable GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT. Setting this value lower (such as the default of 100) restricts the number of allowed outstanding control buffer items, preventing memory exhaustion from unthrottled frames. However, setting this value too low might block legitimate high-throughput traffic, so it should be thoroughly tested.
In addition to application-level fixes, organizations should implement network-level mitigations. Deploying web application firewalls or reverse proxies with strict HTTP/2 frame rate limits can block connections that exhibit abnormal RST_STREAM patterns. Monitoring key performance metrics, such as memory usage growth rate and HTTP/2 connection lifetimes, can help detect active exploitation attempts.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
gRPC-Go gRPC | < 1.82.1 | 1.82.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 | 8.6 |
| Impact | Denial of Service (DoS) & Authorization Bypass |
| Exploit Status | Proof of Concept (PoC) available |
| KEV Status | Not listed |
The software does not properly control the allocation and maintenance of a limited resource, enabling an actor to influence the amount of resources consumed.
A critical HTML sanitization bypass vulnerability in the Ruby library Loofah allows unauthenticated remote attackers to execute Stored Cross-Site Scripting (XSS) attacks. By using semicolon-less numeric character references (NCRs) to encode protocol characters, attackers can evade backend URI verification filters while ensuring the malicious protocol is successfully decoded and executed by client-side web browsers.
An unauthenticated memory-leak Denial of Service (DoS) vulnerability exists in the Node.js Adapter for Hono (@hono/node-server) during the WebSocket handshake upgrade process. If a client initiates a WebSocket upgrade but the process is aborted or fails, resources are permanently retained in memory, leading to heap exhaustion.
An issue in rails-html-sanitizer allowed attackers to bypass restrictions on SVG reference elements (such as <use> or <feImage>) when specific custom configurations allowed these tags. Because the sanitizer only restricted the legacy 'xlink:href' attribute to local references, modern browsers supporting plain 'href' attributes according to the SVG 2 specification would load external resources. This could lead to Cross-Site Scripting (XSS) or user tracking.
An input validation flaw in GitPython allows remote attackers to exfiltrate system environment variables and bypass safe-protocol restrictions via crafted repository URLs passed to the clone API.
A Denial of Service (DoS) vulnerability has been identified in the Node.js XML parsing library fast-xml-parser. The flaw allows unauthenticated remote attackers to cause severe CPU exhaustion, event-loop blocking, and system crashes by sending a crafted XML payload containing repeated DOCTYPE declarations that bypass recursive entity expansion protections.
The high-performance Node.js image processing library sharp inherits several high and medium-severity security vulnerabilities from its underlying native dependency libvips. These include integer overflows in dimensions calculation, heap-based buffer overflows in GIF/TIFF and JPEG2000 processing, and out-of-bounds reads in the EXIF directory decoder, enabling denial of service and potential code execution.