Vulnerabilities in pkg:npm/node-opcua-client

PACKAGE
Advisory Identifier: GHSA-r2pf-9cw4-5j65
Advisory Summary

CVE-2026-68904 is a HIGH (CVSS 7.0) remote code execution vulnerability (CWE-400: Uncontrolled Resource Consumption) affecting node-opcua libraries in the npm ecosystem. The issue involves tcp socket leak (fin-wait-2) via keepalive reconnection cycle - resource exhaustion. Remediation is available by upgrading affected packages to version 2.170.0.

1 Known Advisory Record(s)
Package Vulnerability Intelligence

pkg:npm/node-opcua-client

1 Known Advisory Record(s)

Vulnerability advisories affecting package pkg:npm/node-opcua-client. Select an advisory below to view technical details or fixes.

Advisory ID CVE / NVD Severity Summary
GHSA-r2pf-9cw4-5j65 CVE-2026-68904 HIGH node-opcua: TCP Socket Leak (FIN-WAIT-2) via keepalive reconnection cycle - Resource Exhaustion

CVE-2026-68904 at a Glance

CVE Identifier CVE-2026-68904
GHSA Identifier GHSA-r2pf-9cw4-5j65
Severity HIGH
CVSS v3.1 Base Score 7.0
CWE Classification CWE-400: Uncontrolled Resource Consumption
Affected Product node-opcua
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 7.0

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:H).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality Low (C:L)
Integrity Low (I:L)
Availability High (A:H)

How to Fix CVE-2026-68904

To remediate this vulnerability, upgrade all affected node-opcua dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

node-opcua-transport fixed: 2.170.0
npm install node-opcua-transport@2.170.0
node-opcua-client fixed: 2.170.0
npm install node-opcua-client@2.170.0
node-opcua fixed: 2.170.0
npm install node-opcua@2.170.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls node-opcua-transport

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-68904, inspect your project dependencies using npm:

npm ls node-opcua-transport

Analyze the terminal output to locate any version of node-opcua in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.170.0), your application is affected.

Note: The npm ls node-opcua-transport command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-400: Uncontrolled Resource Consumption, where the product does not properly control the allocation and maintenance of a limited resource. In node-opcua, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

SUMMARY ------- A combination of bugs in node-opcua causes unlimited TCP socket accumulation (FIN-WAIT-2 state) during automatic reconnection, leading to memory exhaustion and eventual container/process crash (OOM kill). The issue is triggered by the default configuration (keepSessionAlive: true) when the OPC UA server has clock skew relative to the client. Affected version: Tested on 2.169.0 (latest as of April 2026). ENVIRONMENT ----------- - Node.js: v24.11.0 - node-opcua: 2.169.0 - OS: Linux (containerized via Podman, slirp4netns networking) - OPC UA Server: Industrial PLC (opc.tcp endpoint), clock skew of ~50 minutes ahead of client - Client config: keepSessionAlive: true (default), keepAliveInterval: 3000, securityMode: None, securityPolicy: None ROOT CAUSE ANALYSIS ------------------- Bug #1 - ClientTCP_transport._on_ACK_response() uses socket.end() instead of socket.destroy() File: node-opcua-transport/src/client_tcp_transport.ts, _on_ACK_response() method When the HEL/ACK handshake fails during a reconnection attempt, the error handler calls socket.end(): if (err || !data) { externalCallback(err || new Error("no data")); if (this._socket) { this._socket.end(); // <- sends TCP FIN, leaves socket in FIN-WAIT-2 } } socket.end() sends a TCP FIN and waits for the peer to close its side. If the peer doesn't respond (common with PLCs), the socket remains in FIN-WAIT-2 state indefinitely, leaking file descriptors and memory. During rapid reconnection cycles (triggered by Bug #2 below), every failed HEL/ACK creates a new leaked socket. --- Bug #2 - ClientSessionKeepAliveManager._ping_server() treats BadInvalidTimestamp as network outage File: node-opcua-client/src/client_session_keepalive_manager.ts, _ping_server() method The keepalive manager reads Server.ServerStatus.CurrentTime on each ping cycle. If the server responds with BadInvalidTimestamp (because the client's RequestHeader.timestamp falls outside the server's tolerance window due to clock skew), the manager treats this as a fatal network error: // Any error -> emit("failure") -> terminateConnection() -> forceConnectionBreak() This triggers a full transport-level reconnection on every keepalive cycle (every keepAliveInterval ms). Combined with Bug #1, each reconnection attempt leaks one TCP socket in FIN-WAIT-2. Impact amplification: With keepAliveInterval: 3000 (3 seconds), the client leaks ~20 sockets/minute, ~1200/hour, exhausting resources in hours. REPRODUCTION STEPS ------------------ 1. Set up an OPC UA server with a clock skewed more than the server's timestamp tolerance ahead of the client. 2. Connect using node-opcua with default settings (keepSessionAlive: true). 3. Monitor TCP sockets: ss -antp | grep FIN-WAIT-2 | wc -l 4. Observe FIN-WAIT-2 count growing continuously (approximately one per keepalive interval). 5. Eventually the process runs out of file descriptors or memory and crashes. SUGGESTED FIXES --------------- For Bug #1 (_on_ACK_response): // Replace socket.end() with socket.destroy() if (this._socket) { this._socket.destroy(); } For Bug #2 (_ping_server): Distinguish between transport-level errors (actual network outage) and application-level OPC UA status codes like BadInvalidTimestamp. The latter indicates the server is reachable and the session is alive - only the timestamp validation failed. The keepalive should not trigger reconnection. REPORTER -------- Marco Velluso @Velluso [velluso.marco64@gmail.com](mailto:velluso.marco64@gmail.com) Requesting CVE assignment and credit as reporter upon fix publication.

CVE-2026-68904 Affected node-opcua Versions

3 component(s)
Fixed Versions:
2.170.0
Product / Package Ecosystem Affected Versions Fixed Version
node-opcua-transport
npm
≥ 2.0.0
< 2.170.0
2.170.0
node-opcua-client
npm
≥ 2.0.0
< 2.170.0
2.170.0
node-opcua
npm
≥ 2.0.0
< 2.170.0
2.170.0

References

Frequently Asked Questions

What is CVE-2026-68904?
CVE-2026-68904 is a security vulnerability in node-opcua involving TCP Socket Leak (FIN-WAIT-2) via keepalive reconnection cycle - Resource Exhaustion under CWE-400: Uncontrolled Resource Consumption.
Which node-opcua versions are affected?
Affected versions include releases prior to 2.170.0 across affected packages: node-opcua-transport, node-opcua-client, node-opcua.
What version fixes CVE-2026-68904?
Upgrading to 2.170.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is node-opcua-transport affected?
Yes, node-opcua-transport is affected in releases prior to 2.170.0. Upgrade your dependency to 2.170.0 or later.
Is node-opcua-client affected?
Yes, node-opcua-client is affected in releases prior to 2.170.0. Upgrade your dependency to 2.170.0 or later.
What is the CVSS score of CVE-2026-68904?
CVE-2026-68904 has a CVSS v3.1 base score of 7.0 (HIGH) with vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:H.
What CWE is associated with CVE-2026-68904?
CVE-2026-68904 is classified under CWE-400: Uncontrolled Resource Consumption (The product does not properly control the allocation and maintenance of a limited resource.).
How can I check npm dependencies for CVE-2026-68904?
Run the dependency tree command: 'npm ls node-opcua-transport'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-r2pf-9cw4-5j65",
  "modified" : "2026-09-16T16:19:21Z",
  "published" : "2026-09-16T16:19:21Z",
  "aliases" : [ "CVE-2026-68904" ],
  "summary" : "node-opcua: TCP Socket Leak (FIN-WAIT-2) via keepalive reconnection cycle - Resource Exhaustion",
  "details" : "SUMMARY\n-------\nA combination of bugs in node-opcua causes unlimited TCP socket accumulation (FIN-WAIT-2 state) during automatic reconnection, leading to memory exhaustion and eventual container/process crash (OOM kill). The issue is triggered by the default configuration (keepSessionAlive: true) when the OPC UA server has clock skew relative to the client.\n\nAffected version: Tested on 2.169.0 (latest as of April 2026).\n\nENVIRONMENT\n-----------\n- Node.js: v24.11.0\n- node-opcua: 2.169.0\n- OS: Linux (containerized via Podman, slirp4netns networking)\n- OPC UA Server: Industrial PLC (opc.tcp endpoint), clock skew of ~50 minutes ahead of client\n- Client config: keepSessionAlive: true (default), keepAliveInterval: 3000, securityMode: None, securityPolicy: None\n\nROOT CAUSE ANALYSIS\n-------------------\n\nBug #1 - ClientTCP_transport._on_ACK_response() uses socket.end() instead of socket.destroy()\n\nFile: node-opcua-transport/src/client_tcp_transport.ts, _on_ACK_response() method\n\nWhen the HEL/ACK handshake fails during a reconnection attempt, the error handler calls socket.end():\n\n    if (err || !data) {\n        externalCallback(err || new Error(\"no data\"));\n        if (this._socket) {\n            this._socket.end();   // <- sends TCP FIN, leaves socket in FIN-WAIT-2\n        }\n    }\n\nsocket.end() sends a TCP FIN and waits for the peer to close its side. If the peer doesn't respond (common with PLCs), the socket remains in FIN-WAIT-2 state indefinitely, leaking file descriptors and memory.\nDuring rapid reconnection cycles (triggered by Bug #2 below), every failed HEL/ACK creates a new leaked socket.\n\n---\n\nBug #2 - ClientSessionKeepAliveManager._ping_server() treats BadInvalidTimestamp as network outage\n\nFile: node-opcua-client/src/client_session_keepalive_manager.ts, _ping_server() method\n\nThe keepalive manager reads Server.ServerStatus.CurrentTime on each ping cycle. If the server responds with BadInvalidTimestamp (because the client's RequestHeader.timestamp falls outside the server's tolerance window due to clock skew), the manager treats this as a fatal network error:\n\n    // Any error -> emit(\"failure\") -> terminateConnection() -> forceConnectionBreak()\n\nThis triggers a full transport-level reconnection on every keepalive cycle (every keepAliveInterval ms). Combined with Bug #1, each reconnection attempt leaks one TCP socket in FIN-WAIT-2.\nImpact amplification: With keepAliveInterval: 3000 (3 seconds), the client leaks ~20 sockets/minute, ~1200/hour, exhausting resources in hours.\n\nREPRODUCTION STEPS\n------------------\n1. Set up an OPC UA server with a clock skewed more than the server's timestamp tolerance ahead of the client.\n2. Connect using node-opcua with default settings (keepSessionAlive: true).\n3. Monitor TCP sockets: ss -antp | grep FIN-WAIT-2 | wc -l\n4. Observe FIN-WAIT-2 count growing continuously (approximately one per keepalive interval).\n5. Eventually the process runs out of file descriptors or memory and crashes.\n\nSUGGESTED FIXES\n---------------\n\nFor Bug #1 (_on_ACK_response):\n\n    // Replace socket.end() with socket.destroy()\n    if (this._socket) {\n        this._socket.destroy();\n    }\n\nFor Bug #2 (_ping_server):\nDistinguish between transport-level errors (actual network outage) and application-level OPC UA status codes like BadInvalidTimestamp. The latter indicates the server is reachable and the session is alive - only the timestamp validation failed. The keepalive should not trigger reconnection.\n\nREPORTER\n--------\nMarco Velluso @Velluso\n[velluso.marco64@gmail.com](mailto:velluso.marco64@gmail.com)\nRequesting CVE assignment and credit as reporter upon fix publication.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "node-opcua-transport"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.0"
      }, {
        "fixed" : "2.170.0"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "npm",
      "name" : "node-opcua-client"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.0"
      }, {
        "fixed" : "2.170.0"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "npm",
      "name" : "node-opcua"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.0"
      }, {
        "fixed" : "2.170.0"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/node-opcua/node-opcua/security/advisories/GHSA-r2pf-9cw4-5j65"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/node-opcua/node-opcua/pull/1497"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/node-opcua/node-opcua/commit/1959cbb8946b386d2e24a1cce05b7148099d36e7"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/node-opcua/node-opcua/commit/481664fa6ba8204737c5a92797ff68c3ae780c1c"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/node-opcua/node-opcua/commit/4d59197e2dbd82791d7f36dad7da178715e0c27a"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/node-opcua/node-opcua/commit/dc406fd2d364aa69dd173be21ed32a7ff425017a"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/node-opcua/node-opcua"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/node-opcua/node-opcua/releases/tag/v2.170.0"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-400" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-09-16T16:19:21Z",
    "nvd_published_at" : null
  }
}