CVE-2026-86065 Overview
CVE-2026-86065 is a resource exhaustion vulnerability [CWE-770] affecting Klever-Go, the Go implementation of the Klever blockchain protocol. The flaw resides in the default-open GET /subscribe WebSocket endpoint defined in network/api/websocket/routes.go. The endpoint accepts unauthenticated WebSocket clients with permissive origin handling, does not call SetReadLimit to bound message size, and enforces no cap on live connections. Because the REST and WebSocket API run inside the node process, memory or scheduler exhaustion can crash the node and interrupt P2P and consensus participation. The issue is fixed in Klever-Go version 1.7.20.
Critical Impact
A single unauthenticated remote client can exhaust node memory, goroutines, and file descriptors, crashing the blockchain node and disrupting consensus participation.
Affected Products
- Klever-Go (Go implementation of the Klever blockchain protocol)
- All versions prior to 1.7.20
- Nodes exposing the /subscribe WebSocket endpoint
Discovery Timeline
- 2026-09-23 - CVE-2026-86065 published to NVD
- 2026-09-23 - Last updated in NVD database
Technical Details for CVE-2026-86065
Vulnerability Analysis
The vulnerability stems from missing resource bounds across the WebSocket subscription pipeline. The /subscribe endpoint upgrades unauthenticated HTTP requests to WebSocket connections without enforcing per-IP or global connection caps. Once upgraded, the connection bypasses the global HTTP request throttler, which counts only standard REST requests.
Inside SocketHub.HandleClientInsertion, the server accepts an unbounded address list that expands the internal addressSubscription map. The client.loopIn reader continues consuming frames without a size limit because SetReadLimit is never called. One attacker can grow subscription maps arbitrarily. Many attackers can retain goroutines, buffered channels, and socket descriptors until the node exhausts memory or scheduler capacity.
Because the API server shares its process with the consensus engine, exhaustion of any of these resources halts P2P messaging and consensus participation on the affected node.
Root Cause
The root cause is missing input and resource bounds [CWE-770] on the WebSocket path. Four controls were absent: a node-wide live-connection cap, a per-IP connection cap, a per-call address cap on /subscribe, and a per-connection cumulative address cap. The frame read limit was also unset, allowing arbitrarily large inbound messages.
Attack Vector
A remote unauthenticated attacker sends WebSocket upgrade requests to /subscribe over the network. The attacker either opens many concurrent connections to consume descriptors and goroutines, or sends oversized subscribe payloads with large address lists to bloat internal maps and buffered channels. No user interaction or privileges are required.
// Patch: config/antiflood.go — new bounding parameters (v1.7.20)
// WebSocketConnections caps simultaneous live /subscribe WebSocket connections
// node-wide; the gin throttlers above do not bound live WS connections. 0 = unlimited.
WebSocketConnections uint32 `yaml:"webSocketConnections"`
// WebSocketConnectionsPerIP caps simultaneous live /subscribe connections from a
// single source IP. Behind a reverse proxy all clients share the proxy IP, so size
// this accordingly or set 0 to disable the per-IP cap. 0 = unlimited.
WebSocketConnectionsPerIP uint32 `yaml:"webSocketConnectionsPerIP"`
// WebSocketMaxAddressesPerSubscribe caps addresses accepted in one /subscribe call.
// The inbound frame read limit is derived from this so a maximal subscribe always
// fits. 0 = built-in default.
WebSocketMaxAddressesPerSubscribe uint32 `yaml:"webSocketMaxAddressesPerSubscribe"`
// WebSocketMaxAddressesPerClient caps the total addresses one connection may watch
// across all of its subscribe calls. 0 = built-in default.
WebSocketMaxAddressesPerClient uint32 `yaml:"webSocketMaxAddressesPerClient"`
Source: GitHub Commit b8af922
Detection Methods for CVE-2026-86065
Indicators of Compromise
- Sudden growth in the number of open WebSocket connections to /subscribe from a small set of source IPs.
- Rapid increase in the Klever-Go node process memory footprint, goroutine count, or open file descriptors.
- Node crashes or consensus participation drops coinciding with inbound WebSocket traffic spikes.
- Oversized WebSocket frames or subscribe payloads with unusually large address arrays.
Detection Strategies
- Monitor HTTP upgrade requests to the /subscribe route and alert on repeated upgrades from single IPs.
- Track Go runtime metrics (goroutines, heap size, GC pauses) on Klever-Go nodes and alert on abnormal growth.
- Correlate P2P or consensus disruption events with concurrent WebSocket connection counts.
Monitoring Recommendations
- Instrument node process metrics with Prometheus or an equivalent collector and set thresholds for memory and descriptor usage.
- Log WebSocket connection lifecycles, including source IP, subscribe payload size, and address count per call.
- Forward node and reverse-proxy access logs to a centralized analytics platform for cross-source correlation.
How to Mitigate CVE-2026-86065
Immediate Actions Required
- Upgrade Klever-Go nodes to version 1.7.20 or later without delay.
- Restrict inbound access to the /subscribe endpoint using network ACLs, reverse-proxy rules, or firewall policies.
- Configure the new anti-flood limits (webSocketConnections, webSocketConnectionsPerIP, webSocketMaxAddressesPerSubscribe, webSocketMaxAddressesPerClient) with non-zero values sized to expected client load.
Patch Information
The fix is available in Klever-Go Release v1.7.20. The patch introduces bounded reads, per-IP and node-wide connection caps, and per-call and per-client subscription caps. Details are published in GitHub Security Advisory GHSA-4fwh-wrm6-97xm and merged via Pull Request #76.
Workarounds
- Place the node behind a reverse proxy that enforces WebSocket connection limits, request rate limits, and maximum frame sizes.
- Bind the WebSocket API interface to a private network only and require VPN or peer-authenticated access.
- Disable or firewall the /subscribe endpoint if it is not required by the deployment.
# Example v1.7.20 antiflood configuration (config.yaml)
webSocketConnections: 1000
webSocketConnectionsPerIP: 20
webSocketMaxAddressesPerSubscribe: 256
webSocketMaxAddressesPerClient: 1024
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.