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

CVE-2026-63252: Eclipse Milo DOS Vulnerability

CVE-2026-63252 is a denial of service flaw in Eclipse Milo that allows attackers to exhaust server memory through incomplete message chunks. This post covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-63252 Overview

CVE-2026-63252 is a memory leak vulnerability in Eclipse Milo, an open-source implementation of the OPC Unified Architecture (OPC UA) protocol stack. The flaw affects Eclipse Milo versions 0.6.0 through 1.1.4. UASC (UA Secure Conversation) server transport handlers fail to release retained partial message chunks when a channel disconnects. A remote unauthenticated attacker can repeatedly send incomplete chunks and disconnect, exhausting pooled direct memory and terminating the server. The vulnerability is classified under CWE-401: Missing Release of Memory after Effective Lifetime.

Critical Impact

Remote unauthenticated attackers can trigger denial of service against OPC UA servers by exhausting pooled direct memory, disrupting industrial control system communications.

Affected Products

  • Eclipse Milo 0.6.0 through 1.1.4
  • OPC UA server implementations built on Eclipse Milo UASC transport
  • Industrial and IoT applications depending on eclipse:milo

Discovery Timeline

  • 2026-08-04 - CVE-2026-63252 published to NVD
  • 2026-08-05 - Last updated in NVD database

Technical Details for CVE-2026-63252

Vulnerability Analysis

The vulnerability resides in the UASC server transport layer of Eclipse Milo. OPC UA messages are transmitted as sequences of chunks that the server accumulates in pooled ByteBuf direct memory buffers until a complete message is assembled. When a client disconnects mid-transmission, the server's chunk accumulator retains references to the partial chunks instead of releasing them back to the Netty allocator pool.

An attacker exploits this by opening a TCP connection to the OPC UA endpoint, sending one or more incomplete UASC message chunks, then abruptly disconnecting. Each iteration leaks direct memory. Because Netty's pooled direct memory is finite and typically bounded by the JVM -XX:MaxDirectMemorySize setting, repeated disconnects exhaust the pool and cause OutOfMemoryError, terminating the server process.

Root Cause

The root cause is a missing cleanup path in the chunk decoding pipeline. The ChunkDecoder and associated UASC server handlers did not iterate pending chunks on channel teardown to invoke ReferenceCountUtil.release() on each retained ByteBuf. Netty's reference-counted buffers only return to the pool when their refcount reaches zero, so orphaned references persist for the lifetime of the JVM.

Attack Vector

The attack requires only network reachability to a UASC endpoint. No authentication, user interaction, or session establishment beyond the initial Hello/OpenSecureChannel handshake is required. An attacker scripts a loop that connects, transmits a message header claiming a larger payload than will be sent, writes a partial chunk, and closes the socket.

java
// Patch: ChunkBufferAccumulator releases retained chunks on teardown
// Source: https://github.com/eclipse-milo/milo/commit/459715793ec54b0f33367a14f94264500a0d872b
package org.eclipse.milo.opcua.stack.transport.server.uasc;

import io.netty.buffer.ByteBuf;
import io.netty.util.ReferenceCountUtil;
import java.util.ArrayList;
import java.util.List;

final class ChunkBufferAccumulator {

  private final int initialCapacity;
  private List<ByteBuf> chunkBuffers;

  ChunkBufferAccumulator() {
    this(0);
  }

  ChunkBufferAccumulator(int initialCapacity) {
    this.initialCapacity = initialCapacity;
  }
  // release() iterates chunkBuffers and calls ReferenceCountUtil.release on teardown
}

Source: Eclipse Milo commit 4597157

Detection Methods for CVE-2026-63252

Indicators of Compromise

  • Repeated short-lived TCP connections to OPC UA port 4840 (or configured UASC port) from a single source that terminate before completing a full message
  • Rising Netty pooled direct memory usage without a corresponding increase in legitimate client sessions
  • JVM logs reporting io.netty.util.internal.OutOfDirectMemoryError or OutOfMemoryError: Direct buffer memory
  • Server process crashes or restarts correlated with bursts of incomplete UASC handshakes

Detection Strategies

  • Monitor OPC UA server JVM heap and direct memory metrics for sustained growth without release after client disconnects
  • Alert on high connection-churn rates against UASC endpoints, especially from single IP addresses sending partial payloads
  • Inspect application logs for repeated OpenSecureChannel failures or truncated chunk exceptions from ChunkDecoder

Monitoring Recommendations

  • Collect Netty allocator metrics (PooledByteBufAllocatorMetric) and expose via JMX or Prometheus
  • Deploy network flow monitoring on industrial control network segments hosting OPC UA endpoints
  • Correlate server crash events with upstream firewall or IDS logs for connection-pattern analysis

How to Mitigate CVE-2026-63252

Immediate Actions Required

  • Upgrade Eclipse Milo to a fixed release (post-1.1.4) that includes commit 4597157 from PR #1800
  • Restrict network access to OPC UA endpoints to trusted management and OT VLANs using firewall rules
  • Cap JVM direct memory via -XX:MaxDirectMemorySize and configure the process supervisor to restart on OOM to reduce downtime

Patch Information

The fix is committed to the Eclipse Milo repository as commit 459715793ec54b0f33367a14f94264500a0d872b titled "Release pending UASC chunks on teardown (#1800)." The patch introduces a ChunkBufferAccumulator class that tracks pending ByteBuf chunks and invokes ReferenceCountUtil.release() on all retained buffers when the channel is torn down. Additional coordination details are available in the Eclipse GitLab vulnerability report and the CVE assignment work item.

Workarounds

  • Place OPC UA servers behind a reverse proxy or gateway that enforces per-source connection rate limits and message-completion timeouts
  • Apply firewall rules that block untrusted networks from reaching UASC ports
  • Enable network segmentation between IT and OT zones to reduce the reachable attacker surface
  • Configure aggressive TCP idle and read timeouts on the server socket to close incomplete channels sooner
bash
# Example: iptables rule limiting new connections to OPC UA port 4840
iptables -A INPUT -p tcp --dport 4840 -m conntrack --ctstate NEW \
  -m limit --limit 20/minute --limit-burst 40 -j ACCEPT
iptables -A INPUT -p tcp --dport 4840 -j DROP

# JVM flags to bound and observe direct memory
java -XX:MaxDirectMemorySize=512m \
     -Dio.netty.leakDetection.level=paranoid \
     -jar milo-server.jar

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.