Back to Intelligence

CVE-2026-63252 & Five More Flaws in Eclipse Milo OPC UA Stack: Detection and Remediation Guide for ICS Defenders

SA
Security Arsenal Team
October 15, 2026
13 min read

CISA has published ICS Advisory ICSA-26-288-01 covering six vulnerabilities in the Eclipse Foundation's Eclipse Milo project — a widely used open-source implementation of the OPC UA (IEC 62541) protocol stack in Java. If you operate in the Chemical sector or any other critical infrastructure vertical that uses OPC UA for OT/IT convergence, this advisory demands immediate attention.

The stakes are concrete: successful exploitation of these flaws could allow an attacker to delete protected data, recover user credentials and impersonate legitimate users, or render the server unresponsive to all clients. The highest-rated issue carries a CVSS v3 score of 8.2. Because Eclipse Milo is embedded as a library into countless vendor products, custom gateways, and homegrown integrations — not deployed as a standalone appliance — many organizations won't even know they have it in their environment. That is the real risk here.

Technical Analysis

Affected Products and Versions

The advisory affects two overlapping version ranges of Eclipse Milo:

  • Eclipse Milo >= 0.6.0 and <= 1.1.4 — vulnerable to CVE-2026-63252, CVE-2026-63248, and CVE-2026-60007
  • Eclipse Milo >= 1.0.0 and <= 1.1.4 — vulnerable to CVE-2026-62927, CVE-2026-58080, and CVE-2026-61387

In practical terms, any Milo-based client or server running version 1.1.4 or earlier should be treated as vulnerable. Milo ships as a set of Maven artifacts (org.eclipse.milo), which means the vulnerable code is compiled directly into downstream applications — historian connectors, SCADA middleware, protocol gateways, IIoT platforms, and custom Java services.

Vulnerability Classes and Impact

The six CVEs map to five distinct weakness categories:

Weakness ClassDefender Concern
Incorrect Authorization (CWE-863)Authenticated or partially authenticated clients may perform operations beyond their granted permission set — the enabler for deleting protected data
Missing Authorization (CWE-862)Sensitive OPC UA service calls may be reachable without any authorization check at all
Observable Response Discrepancy (CWE-203)Differential server responses can be used as an oracle to enumerate valid usernames or probe credential state — the stepping stone to credential recovery and impersonation
Missing Release of Memory after Effective Lifetime (CWE-401)Memory leak triggered by crafted request patterns, degrading the server until it stops responding
Missing Release of Resource after Effective Lifetime (CWE-772)Resource exhaustion (sessions, handles, channels) causing denial of service to all legitimate clients

How Exploitation Works — Defender's View

OPC UA servers expose a binary protocol endpoint, by default on TCP/4840 (opc.tcp). The attack surface here does not require endpoint compromise — it is network-reachable protocol abuse:

  1. Reconnaissance: The attacker connects to the OPC UA endpoint and issues FindServers/GetEndpoints service requests to fingerprint the stack. Milo's default endpoint metadata and error behavior can identify it as a Java/Milo implementation.
  2. Credential-oriented attacks: Using the observable response discrepancy flaw, the attacker submits authentication attempts and measures differences in server responses (status codes, timing, error detail) to distinguish valid accounts from invalid ones, then recovers or replays credentials to impersonate legitimate users.
  3. Authorization bypass: Via the incorrect/missing authorization flaws, an authenticated (or in some paths unauthenticated) session invokes service calls — such as Write, Call, or address-space management operations — that should be restricted, enabling deletion or manipulation of protected data in the underlying address space.
  4. Denial of service: Repeated connection/session establishment combined with crafted requests that never trigger proper cleanup drives the memory and resource leaks (CWE-401/772) until the JVM heap is exhausted or session/handle tables are saturated — the server stops responding to all clients, including safety-relevant subscribers.

Critically, OPC UA servers in ICS environments often hold write access to process setpoints, configuration nodes, and audit-relevant data. An authorization bypass at the protocol layer is not an IT inconvenience — it is an OT integrity event.

Exploitation Status

At the time of publication, CISA has not reported confirmed in-the-wild exploitation of these CVEs, and none of the six identifiers appear in the CISA Known Exploited Vulnerabilities catalog. However, the advisory follows coordinated disclosure, which means technical details are now public — the window between advisory release and working PoC for protocol-level flaws is historically short. Treat this as pre-emptive hardening, not retrospective cleanup.

Detection & Response

Detection for protocol-abuse vulnerabilities like these centers on three observable behaviors: anomalous connection volume to OPC UA endpoints (resource exhaustion staging), authentication probing patterns (response-discrepancy oracles), and JVM degradation on Milo hosts (leak exploitation in progress).

Sigma Rules

The following rules target the highest-fidelity, lowest-noise observables. The process-anomaly rule is deliberately scoped: a Java OPC UA server process spawning a shell is almost never legitimate. The network rule assumes you are collecting connection logs (Sysmon EventID 3, Zeek, or firewall logs) with destination port visibility; tune the threshold to your baseline.

YAML
---
title: OPC UA Server Process Spawning Shell or Command Interpreter
id: 3f8a2b71-6c4d-4e19-9a52-7b1d0c3e5f84
status: experimental
description: Detects a Java process (typical for Eclipse Milo-based OPC UA servers) spawning a shell or scripting interpreter. May indicate post-exploitation activity following compromise of an exposed OPC UA endpoint such as those described in ICSA-26-288-01.
references:
  - https://www.cisa.gov/news-events/ics-advisories/icsa-26-288-01
  - https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/01/15
tags:
  - attack.execution
  - attack.t1059
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\java.exe'
      - '\javaw.exe'
  selection_child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
  condition: selection_parent and selection_child
falsepositives:
  - Legitimate Java-based management agents that invoke scripts for maintenance
  - Application server administrative tooling
level: high
---
title: Excessive Connections to OPC UA Endpoint from Single Source
id: 8c1d4e96-2a7b-4f35-b608-9e2c5a1d4f07
status: experimental
description: Detects a high volume of network connections to TCP/4840 (OPC UA) originating from a single source. May indicate resource-exhaustion attacks against Eclipse Milo servers (CVE-2026-60007, CVE-2026-61387 class issues) or endpoint scanning/fuzzing of the OPC UA attack surface.
references:
  - https://www.cisa.gov/news-events/ics-advisories/icsa-26-288-01
  - https://attack.mitre.org/techniques/T1499/
author: Security Arsenal
date: 2026/01/15
tags:
  - attack.impact
  - attack.t1499
logsource:
  category: network_connection
  product: windows
detection:
  selection:
    DestinationPort: 4840
  condition: selection | count(SourceIp) by DestinationIp > 100
  timeframe: 5m
falsepositives:
  - Legitimate OPC UA clients with aggressive reconnection logic after network instability
  - Load-balanced historian polling
level: medium
---
title: Rapid OPC UA Session Establishment from Non-OT Host
id: 5b7e0a43-1d29-4c86-a3f4-6d8b2e9c1053
status: experimental
description: Detects repeated session-oriented connections to OPC UA endpoints from hosts outside expected OT client segments. Session churn against Milo-based servers can drive the missing-resource-release denial of service described in ICSA-26-288-01 and may indicate session table exhaustion attempts.
references:
  - https://www.cisa.gov/news-events/ics-advisories/icsa-26-288-01
  - https://attack.mitre.org/techniques/T1499.004/
author: Security Arsenal
date: 2026/01/15
tags:
  - attack.impact
  - attack.t1499.004
logsource:
  category: firewall
  product: zeek
detection:
  selection:
    dst_port: 4840
    service: 'opcua*'
  condition: selection | count(src_ip) by dst_ip > 50
  timeframe: 10m
falsepositives:
  - Scheduled OPC UA compliance scanners
  - Redundant HMI failover events
level: medium

KQL — Microsoft Sentinel / Defender

This hunt assumes you ingest network telemetry into Sentinel (CommonSecurityLog from firewalls/NDR, or Syslog from Zeek/Corelight sensors monitoring the OT DMZ). It surfaces authentication probing and connection-volume anomalies against OPC UA endpoints — the two pre-DoS behaviors most worth catching early. The CommonSecurityLog variant works with CEF-ingested firewall data; the Syslog variant assumes Zeek conn logs forwarded via the AMA agent.

KQL — Microsoft Sentinel / Defender
// Hunt: Anomalous connection and authentication-adjacent activity against OPC UA endpoints
// Relevant to ICSA-26-288-01 (Eclipse Milo <=1.1.4): response-discrepancy probing and resource exhaustion staging
let Lookback = 24h;
let OpcUaPorts = dynamic([4840, 4843]);
let ConnStats = (
  CommonSecurityLog
  | where TimeGenerated > ago(Lookback)
  | where DestinationPort in (OpcUaPorts)
  | summarize
      ConnectionCount = count(),
      UniqueDestinations = dcount(DestinationIP),
      FirstSeen = min(TimeGenerated),
      LastSeen = max(TimeGenerated)
    by SourceIP, DestinationPort, bin(TimeGenerated, 5m)
);
ConnStats
| where ConnectionCount > 50   // Tune against your baseline; legit clients are steady-state, not bursty
| summarize
    TotalConnections = sum(ConnectionCount),
    BurstWindows = count(),
    Targets = make_set(DestinationPort)
  by SourceIP
| where TotalConnections > 200 or BurstWindows > 4
| project SourceIP, TotalConnections, BurstWindows, Targets
| order by TotalConnections desc;

// Complementary: correlate with Zeek Syslog ingest for OPC UA service-level detail
Syslog
| where TimeGenerated > ago(Lookback)
| where SyslogMessage has_all ("4840") and SyslogMessage has_any ("CreateSession", "ActivateSession", "CloseSession")
| extend SourceHost = extract(@"src=([0-9.]+)", 1, SyslogMessage)
| summarize SessionOps = count() by SourceHost, bin(TimeGenerated, 10m)
| where SessionOps > 100   // Session churn indicates CloseSession-without-release patterns (CWE-772 abuse)
| order by SessionOps desc;

Velociraptor VQL

Use this artifact to identify which hosts are actually running Milo-based applications (Java processes with Milo on the classpath or listening on OPC UA ports) — essential for scoping remediation when the library is embedded in third-party products. Pair it with connection state to spot exhaustion in progress.

VQL — Velociraptor
-- Identify Java processes likely running Eclipse Milo OPC UA stacks and their network exposure
-- Scope: find Milo artifacts on disk + correlate java processes listening on 4840

LET milo_artifacts = SELECT FullPath, Size, Mtime
FROM glob(globs='/**/*.jar', root='/')
WHERE FullPath =~ '(?i)milo'
   OR FullPath =~ '(?i)org\.eclipse\.milo'

LET listeners = SELECT Pid, Name, LocalAddress, LocalPort, Status
FROM netstat()
WHERE LocalPort in (4840, 4843)
  AND Status = 'LISTEN'

LET java_procs = SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Name =~ '(?i)java'

SELECT
  java_procs.Pid AS Pid,
  java_procs.Name AS ProcessName,
  java_procs.CommandLine AS CommandLine,
  java_procs.Username AS RunAs,
  listeners.LocalAddress AS BindAddress,
  listeners.LocalPort AS OpcUaPort
FROM java_procs
JOIN listeners ON java_procs.Pid = listeners.Pid

Remediation Script

Because Milo is a build-time dependency, "patching" means finding it in your software inventory and forcing a version bump, plus verifying network exposure is restricted. This Bash script sweeps Linux build hosts, CI workspaces, and deployed application directories for vulnerable Milo versions and flags exposed OPC UA listeners.

Bash / Shell
#!/bin/bash
# Eclipse Milo ICSA-26-288-01 exposure sweep
# Usage: sudo ./milo_exposure_sweep.sh [scan_root]
# Identifies vulnerable Milo versions in Maven/Gradle artifacts and exposed OPC UA listeners.

SCAN_ROOT="${1:-/}"
VULN_MAX="1.1.4"
REPORT="milo_exposure_$(date +%Y%m%d_%H%M%S).txt"

echo "=== Eclipse Milo Exposure Sweep — ICSA-26-288-01 ===" | tee "$REPORT"
echo "Scan root: $SCAN_ROOT | Vulnerable: Milo <= ${VULN_MAX}" | tee -a "$REPORT"

# 1. Find Milo JARs and extract version strings
echo -e "\n[1] Milo artifacts on disk:" | tee -a "$REPORT"
find "$SCAN_ROOT" -type f \( -name "*milo*.jar" -o -path "*org/eclipse/milo*" \) 2>/dev/null | while read -r jar; do
    ver=$(basename "$jar" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
    if [ -n "$ver" ]; then
        # Compare version: flag anything <= 1.1.4
        if [ "$(printf '%s\n%s\n' "$ver" "$VULN_MAX" | sort -V | head -1)" = "$ver" ]; then
            echo "  VULNERABLE: $jar (version $ver)" | tee -a "$REPORT"
        else
            echo "  OK:         $jar (version $ver)" | tee -a "$REPORT"
        fi
    else
        echo "  REVIEW:     $jar (version could not be determined — inspect manifest)" | tee -a "$REPORT"
    fi
done

# 2. Check build files for declared Milo dependencies
echo -e "\n[2] Build-file declarations (pom.xml / build.gradle):" | tee -a "$REPORT"
grep -rl "org.eclipse.milo" "$SCAN_ROOT" --include="pom.xml" --include="*.gradle" --include="*.gradle.kts" 2>/dev/null | while read -r buildfile; do
    echo "  FOUND in: $buildfile" | tee -a "$REPORT"
    grep -A2 "org.eclipse.milo" "$buildfile" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | sort -u | while read -r ver; do
        echo "    -> declared version: $ver" | tee -a "$REPORT"
    done
done

# 3. Detect exposed OPC UA listeners and their owning processes
echo -e "\n[3] OPC UA listeners (TCP 4840/4843):" | tee -a "$REPORT"
ss -tlnp 2>/dev/null | grep -E ':(4840|4843)\b' | while read -r line; do
    echo "  LISTENER: $line" | tee -a "$REPORT"
done
if ! ss -tln 2>/dev/null | grep -qE ':(4840|4843)\b'; then
    echo "  None found on this host." | tee -a "$REPORT"
fi

# 4. Verify listeners are not bound to 0.0.0.0 (unrestricted exposure)
echo -e "\n[4] Exposure check:" | tee -a "$REPORT"
if ss -tln 2>/dev/null | grep -E '0\.0\.0\.0:(4840|4843)\b' >/dev/null; then
    echo "  WARNING: OPC UA endpoint bound to 0.0.0.0 — reachable from any interface. Restrict binding or apply firewall policy." | tee -a "$REPORT"
else
    echo "  No wildcard-bound OPC UA endpoints detected." | tee -a "$REPORT"
fi

echo -e "\nSweep complete. Report: $REPORT"
echo "Next step: upgrade Milo dependencies to the fixed release per https://www.cisa.gov/news-events/ics-advisories/icsa-26-288-01 and rebuild/redeploy dependent applications."

Remediation

1. Inventory first — this is the hard part. Milo is a library, not a product you installed. Run the sweep script above across build servers, artifact repositories (Nexus/Artifactory), and deployed application directories. Query your SBOM if you have one (org.eclipse.milo group ID). Ask OT software vendors directly whether their products embed Milo and at what version — many protocol gateways and IIoT connectors do.

2. Upgrade to the fixed release. Update all Milo dependencies to the patched version referenced in CISA ICSA-26-288-01 and the Eclipse Milo project's security release notes. Because the vulnerable range tops out at 1.1.4, any release still at or below that version is exposed. After bumping the dependency, rebuild and redeploy — a pom.xml change does nothing until the fat JAR or container image is regenerated and rolled out.

3. Enforce network-layer compensating controls immediately (do not wait for the patch cycle):

  • Restrict TCP/4840 (and any TLS OPC UA ports in use, e.g., 4843) to an explicit allowlist of known OPC UA client IPs — historians, HMIs, and engineering workstations. There is almost never a legitimate reason for an OPC UA endpoint to be reachable from the general user VLAN, let alone the internet. CISA specifically recommends minimizing network exposure for all control system devices.
  • Place OPC UA servers behind an industrial DMZ with unidirectional or brokered access where architecture permits.
  • Confirm OPC UA endpoints are not bound to 0.0.0.0 unless required, and never to public interfaces.

4. Harden the application configuration:

  • Enforce OPC UA security mode Sign & Encrypt with validated certificates — never None or Sign only — on all endpoints. This blunts the credential-recovery and impersonation paths.
  • Disable anonymous authentication where the application permits it; require certificate-based or strong user-token authentication.
  • Where the embedding application exposes authorization configuration, audit role mappings to ensure write/call operations are denied by default and granted explicitly — this directly mitigates the incorrect/missing authorization flaws until the patch lands.

5. Monitor during the exposure window. Deploy the Sigma rules and KQL hunts above with baselined thresholds. Alert on JVM heap exhaustion patterns and session-table growth on Milo hosts — those are your tripwires for in-progress DoS exploitation.

6. Follow CISA's standard ICS guidance from the advisory: implement defense-in-depth, isolate control networks behind firewalls, use secure remote access (updated VPNs, not port-forwarding), and conduct proper risk assessment before deploying changes to production OT systems — test the rebuilt applications in a staging environment first, since OPC UA stack upgrades can alter session and certificate behavior.

Official references:

Do not wait for a KEV listing to act. Protocol-level authorization and credential-oracle flaws in an OT-facing stack are precisely the class of vulnerability that gets weaponized quietly — in environments where defenders have the least visibility.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.