CVE-2023-39533 Overview
CVE-2023-39533 is a resource exhaustion vulnerability in go-libp2p, the Go implementation of the libp2p Networking Stack. This vulnerability allows a malicious peer to exploit large RSA keys to force a node to spend excessive time performing signature verification operations, resulting in denial of service conditions.
The vulnerability exists within the core/crypto module of go-libp2p and can be triggered during the Noise handshake protocol and the libp2p x509 extension verification step. Prior to the patched versions, there were no size restrictions on RSA keys used during cryptographic operations, enabling attackers to submit keys of arbitrary size that consume disproportionate computational resources during verification.
Critical Impact
Malicious peers can exhaust node resources through large RSA key signature verification, causing denial of service and potentially disrupting decentralized network operations.
Affected Products
- libp2p go-libp2p versions prior to 0.27.8
- libp2p go-libp2p versions prior to 0.28.2
- libp2p go-libp2p version 0.29.0 (prior to 0.29.1)
Discovery Timeline
- August 8, 2023 - CVE-2023-39533 published to NVD
- November 21, 2024 - Last updated in NVD database
Technical Details for CVE-2023-39533
Vulnerability Analysis
This vulnerability affects the cryptographic key handling within go-libp2p's core/crypto module. The fundamental issue is the absence of upper bounds on RSA key sizes accepted during peer authentication and handshake operations.
RSA signature verification is computationally expensive, with verification time increasing significantly with key size. Without restrictions, an attacker can craft connections using extremely large RSA keys (e.g., 16384 bits or larger), causing the target node to expend substantial CPU cycles verifying these signatures. This occurs during two critical operations: the Noise handshake protocol used for secure channel establishment, and the x509 certificate extension verification process used in libp2p's identity system.
The attack can be mounted remotely by any peer attempting to establish a connection, requiring no authentication or special privileges. Multiple simultaneous attack connections can amplify the resource exhaustion effect, potentially bringing nodes offline.
Root Cause
The root cause is improper resource management (CWE-770: Allocation of Resources Without Limits or Throttling) in the RSA key parsing and verification routines. The go-libp2p library did not enforce any maximum key size limit when accepting RSA public keys from peers. While a minimum key size of 2048 bits was enforced for security purposes, no corresponding maximum was defined, creating an asymmetric vulnerability where attackers could impose arbitrary computational costs on victims.
Attack Vector
The attack vector is network-based. An attacker initiates a connection to a vulnerable go-libp2p node and presents an RSA public key of excessive size during the cryptographic handshake. The target node is forced to perform signature verification operations on this oversized key, consuming CPU resources. The attack requires no user interaction and can be executed from any network position that can reach the target node.
The following patches demonstrate the fix implemented to restrict RSA keys to a maximum of 8192 bits:
// Go TLS handshake client-side restriction
// Source: https://github.com/golang/go/commit/2350afd2e8ab054390e284c95d5b089c142db017
return nil
}
+// maxRSAKeySize is the maximum RSA key size in bits that we are willing
+// to verify the signatures of during a TLS handshake.
+const maxRSAKeySize = 8192
+
// verifyServerCertificate parses and verifies the provided chain, setting
// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
// Go TLS handshake server-side enforcement
// Source: https://github.com/golang/go/commit/2350afd2e8ab054390e284c95d5b089c142db017
c.sendAlert(alertBadCertificate)
return errors.New("tls: failed to parse client certificate: " + err.Error())
}
+ if certs[i].PublicKeyAlgorithm == x509.RSA && certs[i].PublicKey.(*rsa.PublicKey).N.BitLen() > maxRSAKeySize {
+ c.sendAlert(alertBadCertificate)
+ return fmt.Errorf("tls: client sent certificate containing RSA key larger than %d bits", maxRSAKeySize)
+ }
}
if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
// go-libp2p core/crypto RSA key size restriction
// Source: https://github.com/libp2p/go-libp2p/commit/0cce607219f3710addc7e18672cffd1f1d912fbb
var MinRsaKeyBits = 2048
+var maxRsaKeyBits = 8192
+
// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key
// that's smaller than MinRsaKeyBits bits. In test
var ErrRsaKeyTooSmall error
+var ErrRsaKeyTooBig error = fmt.Errorf("rsa keys must be <= %d bits", maxRsaKeyBits)
func init() {
if _, ok := os.LookupEnv(WeakRsaKeyEnv); ok {
// go-libp2p RSA key generation validation
// Source: https://github.com/libp2p/go-libp2p/commit/0cce607219f3710addc7e18672cffd1f1d912fbb
if bits < MinRsaKeyBits {
return nil, nil, ErrRsaKeyTooSmall
}
+ if bits > maxRsaKeyBits {
+ return nil, nil, ErrRsaKeyTooBig
+ }
priv, err := rsa.GenerateKey(src, bits)
if err != nil {
return nil, nil, err
Detection Methods for CVE-2023-39533
Indicators of Compromise
- Abnormally high CPU utilization during peer connection establishment
- Elevated signature verification times in libp2p node logs
- Connection attempts from peers presenting RSA keys larger than 8192 bits
- Increased latency or timeout errors during Noise handshake operations
Detection Strategies
- Monitor CPU usage patterns during network handshake operations for unusual spikes
- Implement logging for RSA key sizes presented during peer authentication
- Track and alert on connection attempts that fail with certificate validation errors
- Analyze network traffic for unusually large cryptographic payloads during TLS/Noise handshakes
Monitoring Recommendations
- Deploy application performance monitoring (APM) to track handshake operation durations
- Configure alerts for sustained high CPU usage correlated with network activity
- Review go-libp2p node logs for ErrRsaKeyTooBig errors after upgrading to patched versions
- Monitor connection establishment rates and identify peers with abnormal connection patterns
How to Mitigate CVE-2023-39533
Immediate Actions Required
- Update go-libp2p to version 0.27.8, 0.28.2, or 0.29.1 or later depending on your version branch
- Upgrade Go compiler to version 1.20.7 or 1.19.12 or later to include the underlying crypto/tls fixes
- Rebuild and redeploy all applications using the affected go-libp2p versions
- Review network logs for any prior exploitation attempts
Patch Information
The vulnerability has been addressed in go-libp2p versions 0.27.8, 0.28.2, and 0.29.1. These patches restrict RSA keys to a maximum of 8192 bits, preventing the resource exhaustion attack. Additionally, the Go standard library has been patched in versions 1.20.7 and 1.19.12 to enforce the same RSA key size limits in the crypto/tls package.
For detailed patch information, refer to the libp2p Security Advisory and the libp2p Pull Request #2454.
Workarounds
- No known workarounds exist for this vulnerability - updating to patched versions is required
- Consider implementing network-level rate limiting on incoming connections as a temporary measure
- Deploy connection timeouts to limit the duration of handshake operations
- Isolate critical nodes behind reverse proxies or load balancers with connection filtering capabilities
# Verify go-libp2p version in your Go module
go list -m github.com/libp2p/go-libp2p
# Update to patched version
go get github.com/libp2p/go-libp2p@v0.29.1
# Verify Go compiler version
go version
# Ensure output shows go1.20.7+ or go1.19.12+
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


