{"id":"CVE-2026-119188","aliases":["GHSA-8hrf-8g6f-7xwp"],"title":"Forge: Denial of service in TLS record processing via a record interleaved with a fragmented handshake message","titleSource":"GitHub_M","descriptionSource":"OSV","declaredSeverity":"HIGH","description":"### Summary\n\nA 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.\n\n### Details\n\nIn `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.\n\nRFC 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.\n\nnode-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.\n\nThe 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.\n\n### Patches\nFixed 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.\n\n### Workarounds\nWrap 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.\n\n### Proof of concept\n\nInput (server mode), two records, 18 bytes:\n\n  16 03 01 00 06 01 00 00 10 03 01   handshake record: ClientHello header announcing 16 bytes, 2 present\n  15 03 01 00 02 02 28               alert record\n\n  // c = forge.tls.createConnection({server: true, ...})\n  c.process(forge.util.hexToBytes('1603010006010000100301' + '15030100020228'));\n\nOn 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.\n\nRegression 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.\n\n### Impact\n\nApplications 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.","severity":"high","score":7.5,"published":"2026-10-29T19:21:27.347Z","modified":"2026-10-30T23:15:08.387Z","withdrawn":false,"knownExploited":false,"affected":[{"ecosystem":"npm","name":"node-forge","sources":[{"name":"OSV · GHSA-8hrf-8g6f-7xwp","url":"https://osv.dev/vulnerability/GHSA-8hrf-8g6f-7xwp"}],"ranges":[{"events":[{"introduced":"0"},{"fixed":"1.4.1"}],"type":"SEMVER"}],"versions":[],"fixed":["1.4.1"]}],"sourceAffected":[],"references":["https://github.com/digitalbazaar/forge/security/advisories/GHSA-8hrf-8g6f-7xwp","https://github.com/digitalbazaar/forge/commit/700d977d39f9f8f896c55b0763eebb940a2c087e","https://github.com/digitalbazaar/forge/releases/tag/v1.4.1","https://nvd.nist.gov/vuln/detail/CVE-2026-119188","https://github.com/digitalbazaar/forge"],"sources":[{"name":"CVE","id":"CVE-2026-119188","modified":"2026-10-30T16:09:23.948Z","url":"https://www.cve.org/CVERecord?id=CVE-2026-119188"},{"name":"OSV","id":"GHSA-8hrf-8g6f-7xwp","modified":"2026-10-30T23:15:08.387649859Z","url":"https://osv.dev/vulnerability/GHSA-8hrf-8g6f-7xwp"}],"assessments":[{"source":"GitHub_M","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5},{"source":"OSV","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5}],"cve":{"records":[{"id":"CVE-2026-119188","source":"GitHub_M","state":"PUBLISHED","reasons":[],"replacements":[],"disputed":false,"unsupportedWhenAssigned":false,"reserved":"2026-10-29T16:04:48.727Z","published":"2026-10-29T19:21:27.347Z","modified":"2026-10-30T16:09:23.948Z"}],"publishers":[{"name":"GitHub_M","role":"CNA","organizationId":"a0819718-46f1-4df5-94e2-005712e83aaa","modified":"2026-10-29T19:21:27.347Z"},{"name":"CISA-ADP","role":"ADP","organizationId":"134c704f-9b21-4f2e-91b3-4a467353bcc0","modified":"2026-10-30T16:09:23.948Z"}],"references":[{"url":"https://github.com/digitalbazaar/forge/security/advisories/GHSA-8hrf-8g6f-7xwp","tags":["x_refsource_CONFIRM"],"source":"GitHub_M"},{"url":"https://github.com/digitalbazaar/forge/commit/700d977d39f9f8f896c55b0763eebb940a2c087e","tags":["x_refsource_MISC"],"source":"GitHub_M"},{"url":"https://github.com/digitalbazaar/forge/releases/tag/v1.4.1","tags":["x_refsource_MISC"],"source":"GitHub_M"}],"weaknesses":[{"id":"CWE-248","description":"CWE-248: Uncaught Exception","source":"GitHub_M"},{"id":"CWE-476","description":"CWE-476: NULL Pointer Dereference","source":"GitHub_M"}],"applicability":[],"prioritization":[{"source":"CISA-ADP","type":"SSVC","role":"CISA Coordinator","timestamp":"2026-10-30T15:47:07.746474Z","decisions":[{"name":"Exploitation","value":"none"},{"name":"Automatable","value":"yes"},{"name":"Technical Impact","value":"partial"}]}]},"products":[{"vendor":"digitalbazaar","name":"forge","platforms":[],"versions":[{"version":"< 1.4.1","status":"affected"}],"cpes":[],"source":"GitHub_M","url":"https://www.cve.org/CVERecord?id=CVE-2026-119188"}],"remediation":[],"observedAt":"2026-10-30T23:31:48.718Z","kev":{"status":"not-listed","checkedAt":"2026-10-31T07:10:30.687Z"},"coverage":[{"source":"NVD","status":"no-result","checkedAt":"2026-10-29T19:50:36.962Z","attemptedAt":"2026-10-29T19:50:36.962Z"},{"source":"GHSA","status":"no-result","checkedAt":"2026-10-29T19:50:37.612Z","attemptedAt":"2026-10-29T19:50:37.612Z"},{"source":"EUVD","status":"refresh-failed","attemptedAt":"2026-10-29T19:50:35.455Z"},{"source":"EPSS","status":"no-result","checkedAt":"2026-10-29T19:50:37.060Z","attemptedAt":"2026-10-29T19:50:37.060Z"}],"evidence":[],"aiSummary":{"text":"The node-forge library, versions less than 1.4.1, has a denial of service vulnerability in TLS record processing. A peer can trigger a crash by sending a record of another content type while a handshake message is being processed. This can terminate Node.js processes that use the library.","model":"@cf/meta/llama-3.3-70b-instruct-fp8-fast","generatedAt":"2026-10-31T00:01:23.083Z","sources":[{"name":"CVE","url":"https://www.cve.org/CVERecord?id=CVE-2026-119188"},{"name":"OSV","url":"https://osv.dev/vulnerability/GHSA-8hrf-8g6f-7xwp"}]}}