CVE-2023-39325 Overview
CVE-2023-39325 is a resource exhaustion vulnerability affecting Go's HTTP/2 implementation that enables denial of service attacks through rapid stream creation and reset. A malicious HTTP/2 client can rapidly create requests and immediately reset them, causing excessive server resource consumption. While the total number of requests is bounded by the http2.Server.MaxConcurrentStreams setting, resetting an in-progress request allows the attacker to create a new request while the existing one is still executing, effectively bypassing concurrency limits.
This vulnerability is part of the broader "HTTP/2 Rapid Reset" attack class that impacted numerous HTTP/2 implementations in 2023, making it particularly significant for organizations running Go-based services.
Critical Impact
Attackers can cause denial of service by exhausting server resources through rapid HTTP/2 stream resets, potentially affecting all Go-based web services and applications using the affected net/http2 package.
Affected Products
- Golang Go (versions prior to patched releases)
- Golang HTTP/2 library (golang.org/x/net/http2)
- Fedora 37, 38, and 39
- NetApp Astra Trident
- NetApp Astra Trident Autosupport
Discovery Timeline
- 2023-10-11 - CVE-2023-39325 published to NVD
- 2024-11-21 - Last updated in NVD database
Technical Details for CVE-2023-39325
Vulnerability Analysis
This vulnerability exploits a weakness in how Go's HTTP/2 server implementation handles concurrent stream management. Under normal operation, the MaxConcurrentStreams setting limits the number of simultaneous requests a client can make on a single HTTP/2 connection (defaulting to 250 streams). However, the vulnerability arises because the server does not properly account for handler goroutines that are still executing when their associated streams are reset by the client.
When an attacker initiates a request and immediately sends an RST_STREAM frame, the server's concurrency counter decrements, allowing a new stream to be opened. Meanwhile, the handler goroutine for the cancelled request may still be executing, consuming server resources. By rapidly repeating this pattern, an attacker can spawn an unbounded number of handler goroutines, leading to memory exhaustion, CPU saturation, and eventual service unavailability.
The fix introduces a new mechanism that bounds the number of simultaneously executing handler goroutines to the stream concurrency limit. New requests arriving when at the limit are queued until a handler exits. If the request queue grows too large, the server terminates the connection entirely to protect against resource exhaustion.
Root Cause
The root cause is classified as CWE-770: Allocation of Resources Without Limits or Throttling. The HTTP/2 server implementation failed to properly correlate the stream concurrency limit with the actual number of executing request handlers. The decoupling between stream state and handler execution state allowed attackers to bypass intended resource limits through rapid stream reset operations.
Attack Vector
The attack is network-based and can be executed remotely without authentication. An attacker establishes an HTTP/2 connection to a vulnerable Go server and performs the following sequence:
- Open an HTTP/2 stream and send request headers
- Immediately send an RST_STREAM frame to cancel the request
- Open a new stream before the previous handler has completed
- Repeat steps 1-3 at high frequency
This pattern causes the server to accumulate goroutines faster than they can complete, eventually exhausting available memory or causing excessive CPU usage from context switching. The attack requires minimal bandwidth compared to traditional volumetric DDoS attacks, making it particularly efficient.
The default stream concurrency limit is 250 streams per HTTP/2 connection. This value may be adjusted using the golang.org/x/net/http2 package through the Server.MaxConcurrentStreams setting and the ConfigureServer function.
Detection Methods for CVE-2023-39325
Indicators of Compromise
- Unusual patterns of HTTP/2 RST_STREAM frames being sent immediately after request initiation
- Rapid growth in the number of goroutines on Go-based servers
- Elevated memory consumption on HTTP/2 servers without corresponding increase in legitimate traffic
- High rate of incomplete HTTP/2 streams with short durations
Detection Strategies
- Monitor HTTP/2 connection metrics for abnormal RST_STREAM frame rates relative to completed requests
- Implement application performance monitoring (APM) to track goroutine counts and memory allocation patterns
- Deploy network-based intrusion detection systems with signatures for HTTP/2 rapid reset attack patterns
- Review server logs for connections with high stream creation rates combined with minimal response data
Monitoring Recommendations
- Set up alerting thresholds for goroutine count increases that exceed normal operational baselines
- Monitor HTTP/2 server connection duration and stream completion ratios
- Track memory utilization trends on servers running Go-based HTTP/2 services
- Implement rate limiting on HTTP/2 stream creation at the load balancer or reverse proxy level
How to Mitigate CVE-2023-39325
Immediate Actions Required
- Update Go to the latest patched version that includes the fix for CVE-2023-39325
- Update the golang.org/x/net/http2 package if manually configuring HTTP/2 servers
- Consider reducing MaxConcurrentStreams from the default 250 to a lower value appropriate for your workload
- Deploy a reverse proxy or load balancer with HTTP/2 rapid reset attack protection capabilities
Patch Information
Golang has released patches addressing this vulnerability. The fix ensures HTTP/2 servers bound the number of simultaneously executing handler goroutines to the stream concurrency limit. New requests arriving when at the limit are queued until a handler exits, and if the request queue grows too large, the server terminates the connection.
For detailed patch information, refer to:
- Go.dev Changelist #534215
- Go.dev Changelist #534235
- Go.dev Issue #63417
- Go Vulnerability Database GO-2023-2102
Additional vendor advisories are available from Gentoo GLSA 202311-09 and NetApp Advisory NTAP-20231110-0008.
Workarounds
- Deploy HTTP/2-aware load balancers or reverse proxies in front of Go servers to filter malicious traffic patterns
- Temporarily disable HTTP/2 and fall back to HTTP/1.1 if patching is not immediately possible
- Implement connection-level rate limiting to restrict the number of streams a single client can create over time
- Configure firewall rules to limit the rate of new connections from individual IP addresses
# Example: Configure Go HTTP/2 server with reduced MaxConcurrentStreams
# In your Go application, use the http2 package to configure the server:
#
# import "golang.org/x/net/http2"
#
# server := &http.Server{Addr: ":443", Handler: handler}
# http2.ConfigureServer(server, &http2.Server{
# MaxConcurrentStreams: 100, // Reduce from default 250
# })
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

