Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
HIGH severity

CVE-2026-119188 — node-forge

HIGHFix: digitalbazaar/forge@700d977

CVE-2026-119188 is a high-severity (CVSS 7.5) CWE-248 vulnerability in node-forge. A fix is available for node-forge — see the affected versions and patch details below.

Forge: Denial of service in TLS record processing via a record interleaved with a fragmented handshake message

Also known asGHSA-8hrf-8g6f-7xwp
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 30, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-119188.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs35th percentile — riskier than 35% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

CVE-2026-119188 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 398,142 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

4Kother npm packages depend on this — each one inherits the vulnerability until it's patched upstream
node-forgenpm
53.7Mdownloads / week

Description

Summary

A connection created with forge.tls.createConnection() throws an uncaught TypeError from process() when it receives a record of another content type while waiting for the rest of a handshake message that was split across records. A peer can trigger this with 18 bytes before the handshake, without authentication, which terminates Node.js processes that use the documented socket wiring. Fixed in node-forge 1.4.1.

Details

In lib/tls.js, _readRecord() handles a record that arrives while a handshake message split across records is incomplete. If the record has any other content type (change_cipher_spec, alert, application_data or heartbeat), forge correctly reports "Invalid fragmented record." through c.error() with a fatal unexpected_message alert. That fatal error closes and resets the connection, which sets c.record to null. _readRecord() then continues with c.record.ready = true and throws TypeError: Cannot set properties of null (setting 'ready') out of process(). The code is unchanged since the first release.

RFC 5246 section 6.2.1 allows a handshake message to be fragmented across records, and RFC 8446 section 5.1 forbids interleaving handshake messages with other record types. Failing the connection with unexpected_message is the intended behavior; the bug is the crash after the error.

node-forge reports TLS protocol errors through the error callback, so applications do not normally wrap process() in try/catch. When process() is called from a Node.js socket data handler, as in the documented usage, the exception is uncaught and terminates the process.

The fix returns from _readRecord() right after the fatal error. The connection is failed, the alert is sent and the error callback is called as before, and process() no longer throws.

Patches

Fixed in node-forge 1.4.1. The connection still fails with a fatal unexpected_message alert and the error callback, but process() no longer throws.

Workarounds

Wrap every call to connection.process() in try/catch. The connection has already been failed and closed when the exception is thrown, so the exception can be ignored or the socket destroyed.

Proof of concept

Input (server mode), two records, 18 bytes:

16 03 01 00 06 01 00 00 10 03 01 handshake record: ClientHello header announcing 16 bytes, 2 present 15 03 01 00 02 02 28 alert record

// c = forge.tls.createConnection({server: true, ...}) c.process(forge.util.hexToBytes('1603010006010000100301' + '15030100020228'));

On 1.4.0 the error callback receives "Invalid fragmented record.", then process() throws TypeError: Cannot set properties of null (setting 'ready'). A change_cipher_spec, application_data or heartbeat record in place of the alert has the same effect, and a client connection behaves the same with a fragment of a ServerHello. In a Node.js server that calls c.process(data.toString('binary')) from socket.on('data', ...), a client sending these 18 bytes terminates the server process. On 1.4.1 the connection fails with a fatal unexpected_message alert and process() returns normally.

Regression tests in tests/unit/tls.js, "fragmented handshake messages": each of the four other record types after a handshake fragment, in server and client mode, plus same-type continuation records that are still accepted.

Impact

Applications that use node-forge's TLS implementation: connections from forge.tls.createConnection(), including those created by forge.tls.wrapSocket() and the forge.http / forge.xhr TLS connections. Any peer that can connect to a forge TLS server, or any server a forge TLS client connects to, can send 18 bytes before the handshake, without authentication. In Node.js applications using the documented usage, the uncaught exception terminates the process, which drops every connection it serves, and the attacker can repeat it on every restart. There is no confidentiality or integrity impact.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npmnode-forgeall versions1.4.1npm install node-forge@1.4.1

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for node-forge, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update node-forge to 1.4.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-119188 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

Frequently Asked Questions

### Summary A connection created with `forge.tls.createConnection()` throws an uncaught `TypeError` from `process()` when it receives a record of another content type while waiting for the rest of a handshake message that was split across records. A peer can trigger this with 18 bytes before the handshake, without authentication, which terminates Node.js processes that use the documented socket wiring. Fixed in node-forge 1.4.1. ### Details In `lib/tls.js`, `_readRecord()` handles a record that arrives while a handshake message split across records is incomplete. If the record has any other
O3 Security · Impact-Aware SCA

Is CVE-2026-119188 in your dependencies?

Find it across npm, including transitive dependencies.

CVE-2026-119188: node-forge — Fixed in 1.4.1