Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-84445

CVE-2026-84445: gRPC-Go xDS Server DoS Vulnerability

CVE-2026-84445 is a denial of service vulnerability in gRPC-Go that allows unauthenticated attackers to crash servers by sending malformed RPC requests. This article covers the technical details, affected versions, and mitigation.

Published:

CVE-2026-84445 Overview

CVE-2026-84445 is a high-severity denial-of-service vulnerability in gRPC-Go, the Go language implementation of gRPC. Servers created with xds.NewGRPCServer() accept an RPC that contains neither the :authority header nor the Host header. The RouteAndProcess function in internal/xds/server/routing.go assumes an authority value exists and indexes an empty slice, triggering an index-out-of-bounds panic. Because the panic occurs outside the per-RPC goroutine's recovery path, it terminates the entire server process. The flaw is tracked as [CWE-129: Improper Validation of Array Index] and is fixed in versions 1.82.2 and 1.83.2.

Critical Impact

A remote unauthenticated client that can establish a transport connection can crash the entire gRPC server process with a single malformed RPC.

Affected Products

  • gRPC-Go versions prior to 1.82.2 (v1.82.x branch)
  • gRPC-Go versions prior to 1.83.2 (v1.83.x branch)
  • Servers instantiated via xds.NewGRPCServer()

Discovery Timeline

  • 2026-09-14 - CVE-2026-84445 published to NVD
  • 2026-09-14 - Last updated in NVD database

Technical Details for CVE-2026-84445

Vulnerability Analysis

The defect resides in the interaction between the HTTP/2 transport layer and the xDS routing layer of gRPC-Go. The transport code in internal/transport/http2_server.go normalizes incoming headers and deletes the host metadata key after copying its value into :authority. Prior to the patch, no check confirmed that :authority was actually populated when both headers were absent.

Once the request reached RouteAndProcess in internal/xds/server/routing.go, the router called md.Get(":authority") and dereferenced authority[0] unconditionally. Reading index 0 from an empty slice raises a runtime panic. Because the panic propagates on a goroutine that is not covered by the server's per-RPC recover handler, the entire Go process exits and the service becomes unavailable.

In insecure and standard TLS deployments the malformed RPC does not require authentication. Strict mTLS or ALTS deployments require valid transport credentials before the request reaches the vulnerable interceptor path.

Root Cause

The root cause is an unchecked array index [CWE-129] combined with an unmet invariant. Comment A41 in the code asserted that a single, unambiguous authority would always be present by the time execution reached the router. The HTTP/2 server did not enforce that invariant, allowing an empty slice to reach a caller that assumed non-empty input.

Attack Vector

An attacker completes a normal HTTP/2 connection to an xDS-enabled gRPC server and sends a HEADERS frame that omits both :authority and Host. The server processes the stream, dispatches routing, panics on the empty slice access, and the parent process terminates. Repeated crashes prevent service recovery until the underlying deployment is patched.

go
// Patch in internal/transport/http2_server.go
// Source: https://github.com/grpc/grpc-go/commit/93e31b48545e2a8aaeb6e06b47fb249f94e6297f
	delete(mdata, "host")
	}

+	// If :authority is still missing, i.e. no host or :authority header is
+	// present, reject the request as invalid.
+	if len(mdata[":authority"]) == 0 {
+		t.writeEarlyAbort(streamID, s.contentSubtype, status.New(codes.Internal, "no host or :authority header present"), http.StatusBadRequest, !frame.StreamEnded())
+		return nil
+	}
	if frame.StreamEnded() {
		// s is just created by the caller. No lock needed.
		s.state = streamReadDone
go
// Patch in internal/xds/server/routing.go
// Source: https://github.com/grpc/grpc-go/commit/93e31b48545e2a8aaeb6e06b47fb249f94e6297f
	authority := md.Get(":authority")
+	if len(authority) == 0 {
+		return rc.statusErrWithNodeID(codes.Internal, "no :authority header present")
+	}
	vh := findBestMatchingVirtualHostServer(authority[0], rc.vhs)

Detection Methods for CVE-2026-84445

Indicators of Compromise

  • Unexpected process exit of a gRPC server binary with a Go runtime panic: runtime error: index out of range [0] with length 0 stack trace referencing internal/xds/server/routing.go.
  • Sudden termination of gRPC server processes shortly after new inbound HTTP/2 connections from previously unseen sources.
  • Repeated container restarts or Kubernetes pod CrashLoopBackOff events for services using xds.NewGRPCServer().

Detection Strategies

  • Enable HTTP/2 frame-level logging on gRPC servers to identify inbound HEADERS frames missing both :authority and Host pseudo-headers.
  • Instrument gRPC servers with panic recovery middleware that logs the offending stream, remote peer, and header set before the process exits.
  • Compare grpc-go module versions in dependency manifests (go.mod) against the fixed releases v1.82.2 and v1.83.2.

Monitoring Recommendations

  • Alert on abnormal restart rates or SIGABRT/SIGSEGV exit codes on services that expose gRPC/xDS endpoints.
  • Monitor edge proxies for clients sending malformed HTTP/2 requests without host authority information.
  • Correlate service downtime windows with recent inbound connection sources to identify probing behavior.

How to Mitigate CVE-2026-84445

Immediate Actions Required

  • Upgrade gRPC-Go to v1.82.2 on the 1.82.x branch or v1.83.2 on the 1.83.x branch, then rebuild and redeploy all affected binaries.
  • Inventory internal Go services for usage of xds.NewGRPCServer() and prioritize those exposed to untrusted networks.
  • For services that cannot be patched immediately, restrict network exposure to authenticated peers using strict mTLS or ALTS.

Patch Information

The fix landed in upstream pull request #9365 and was cherry-picked to release branches via #9366 and #9367. Fixed releases are available at gRPC-Go v1.82.2 and gRPC-Go v1.83.2. Full technical detail is published in GHSA-2v4p-qf9q-27wj.

Workarounds

  • Front the xDS-enabled gRPC server with a reverse proxy (for example, Envoy) configured to reject HTTP/2 requests missing an authority or host header.
  • Deploy the server behind strict mTLS or ALTS so unauthenticated clients cannot complete the transport handshake required to reach the vulnerable path.
  • Add a server-side unary and stream interceptor that validates the presence of :authority metadata and rejects requests early with codes.Internal before routing.
bash
# Update the gRPC-Go dependency to a fixed release
go get google.golang.org/grpc@v1.83.2
go mod tidy
go build ./...

# Verify the resolved version
go list -m google.golang.org/grpc

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.