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

CVE-2026-54156: node-opcua Denial of Service Vulnerability

CVE-2026-54156 is a denial of service flaw in node-opcua that enables attackers to crash servers through unbounded heap growth. This article covers the technical details, affected versions, and mitigation strategies.

Published:

CVE-2026-54156 Overview

CVE-2026-54156 is a denial-of-service vulnerability in node-opcua, an OPC UA (Open Platform Communications Unified Architecture) implementation for TypeScript and Node.js. Versions prior to 2.166.0 store nonces from OpenSecureChannelRequest and CreateSession in a process-global cache (g_alreadyUsedNonce) without expiration or size limits. An unauthenticated remote attacker can repeatedly open sessions with unique nonces, forcing entries to accumulate across connection cycles. The unbounded heap growth eventually exhausts the Node.js process heap and crashes the server. The issue is fixed in version 2.166.0 [CWE-770].

Critical Impact

Unauthenticated remote attackers can crash node-opcua server processes by exhausting Node.js heap memory, disrupting industrial control and OPC UA telemetry pipelines.

Affected Products

  • node-opcua versions prior to 2.166.0
  • Node.js applications embedding node-opcua-secure-channel
  • OPC UA servers built on the affected library, including industrial and IoT gateways

Discovery Timeline

  • 2026-09-14 - CVE-2026-54156 published to NVD
  • 2026-09-14 - Last updated in NVD database

Technical Details for CVE-2026-54156

Vulnerability Analysis

The vulnerability resides in packages/node-opcua-secure-channel/source/server/server_secure_channel_layer.ts. The nonceAlreadyBeenUsed function tracks previously seen nonces to prevent replay attacks. It stores each nonce, keyed by its base64 hash, in a process-global object named g_alreadyUsedNonce.

The cache has no time-to-live and no maximum size. Entries persist indefinitely, even after the associated session terminates. Session concurrency limits such as maxSessions=10 do not bound the cache because attackers reconnect repeatedly with fresh nonces. The attacker never needs to authenticate to reach the vulnerable code path.

Over time, memory pressure exhausts the default Node.js heap. The server process crashes, disrupting any downstream OPC UA clients that depend on it for industrial telemetry or control signaling.

Root Cause

The root cause is a missing resource management control on cached security material, classified as Allocation of Resources Without Limits or Throttling [CWE-770]. The pre-patch implementation used a plain JavaScript object as an unbounded map:

typescript
const g_alreadyUsedNonce: any = {};
export function nonceAlreadyBeenUsed(nonce?: Nonce): boolean {
    if (!nonce || isEmptyNonce(nonce)) {
        return false;
    }
    const hash = nonce.toString("base64");
    if (Object.prototype.hasOwnProperty.call(g_alreadyUsedNonce, hash)) {
        return true;
    }
    g_alreadyUsedNonce[hash] = { time: new Date() };
    return false;
}

No eviction policy runs against g_alreadyUsedNonce, so every unique nonce contributes a permanent entry.

Attack Vector

An unauthenticated remote attacker repeatedly opens secure channels and sessions against the OPC UA server. Each request carries a unique client nonce, adding a new hash entry to the cache. Because OpenSecureChannelRequest and CreateSession are processed before authentication completes, the attacker does not need valid credentials to trigger allocation.

Sustained connection cycling drives heap usage until the Node.js process aborts with an out-of-memory error.

Detection Methods for CVE-2026-54156

Indicators of Compromise

  • Steady growth of resident memory for the node-opcua server process without corresponding legitimate session growth
  • High rates of OpenSecureChannelRequest and CreateSession messages from a small set of source IP addresses
  • Repeated Node.js FATAL ERROR: Reached heap limit Allocation failed crashes on the OPC UA host

Detection Strategies

  • Baseline normal OPC UA connection and session rates, then alert on unauthenticated connection surges above baseline
  • Correlate secure channel open events with heap size samples exported through Node.js runtime metrics or process.memoryUsage()
  • Inspect application logs for repeated CreateSession requests followed by short-lived or aborted sessions from the same peer

Monitoring Recommendations

  • Export Node.js heap and RSS metrics to a metrics backend and alert on sustained upward trend over hours
  • Monitor OPC UA endpoint TCP connection counts and reset rates at the network layer
  • Track process restart frequency for OPC UA server workloads and alert on repeated unclean exits

How to Mitigate CVE-2026-54156

Immediate Actions Required

  • Upgrade node-opcua to version 2.166.0 or later in all affected deployments
  • Restrict OPC UA endpoint exposure to trusted network segments using firewalls or VPN gateways
  • Restart long-running OPC UA server processes to reclaim any accumulated heap from prior probing

Patch Information

The fix ships in node-opcua 2.166.0. The patch introduces a dedicated nonce_cache.ts module that adds a time-to-live and maximum size to the nonce store. Entries are lazily evicted on lookup once they exceed the TTL, and the oldest entries are dropped when the cache exceeds the maximum size. Defaults set a 4-hour TTL and 50,000-entry limit.

typescript
/** Default time-to-live for nonce entries: 4 hours */
const DEFAULT_TTL_MS = 4 * 3_600_000;
/** Default maximum number of nonce entries */
const DEFAULT_MAX_SIZE = 50_000;

Source: GitHub Commit b82c2939. See also the GitHub Security Advisory GHSA-6wvw-vrw4-363w and Release v2.166.0.

Workarounds

  • Place OPC UA endpoints behind a reverse proxy or firewall that rate-limits new TCP connections from unauthenticated sources
  • Configure process supervisors such as systemd or pm2 to automatically restart the OPC UA server on out-of-memory exit
  • Raise the Node.js heap limit temporarily with --max-old-space-size only as a bridge measure until the patch is deployed
bash
# Upgrade node-opcua to the patched version
npm install node-opcua@^2.166.0

# Verify the installed version
npm ls node-opcua

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

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.