Forge: TLS client crash when the server sends no certificate
Impact
The forge TLS client in node-forge versions before 1.4.1 crashes when a malicious server or on-path attacker removes the server's Certificate message, causing a TypeError. The client fails to check for a missing server certificate, allowing the handshake to continue and throw an exception. This affects applications using the forge TLS client.
Summarized by @cf/meta/llama-3.3-70b-instruct-fp8-fast. Verify details against the original sources.Failing even when verify returns true is needed because the key exchange requires the certificate.
Affected packages
Start with the recorded fix for your release branch. Check your installed version and test compatibility before upgrading. Fixing this advisory does not rule out other vulnerabilities in the release.
| Affected range | Recorded fix |
|---|---|
| Earlier releases before 1.4.1Semantic versions | 1.4.1 |
Version evidence: OSV · GHSA-525v-9gp9-w22h
View original version evidence (0 explicit versions)
Affected products
Vendor version evidence. Product records are separate from automatic dependency matching.
digitalbazaar · GitHub_M
forge
1 range
digitalbazaar · GitHub_M
forge
Compare with this publisher’s ranges. This does not inspect your installation.
affected
< 1.4.1
Other versions: unknown
Original source description
Summary
The forge TLS client's check for a missing server certificate read the wrong property and never ran. A malicious TLS server, or an on-path attacker who removes the server's Certificate message, can make connection.process() throw a TypeError, which crashes applications that use the forge TLS client. Fixed in node-forge 1.4.1.
Details
After ServerHelloDone, tls.handleServerHelloDone() in lib/tls.js is meant to reject a server that sent no certificate with a fatal insufficient_security alert, after consulting the application's verify callback. The check tested c.serverCertificate, which is never set (the certificate is stored as c.session.serverCertificate), so it never ran. The client state machine allows ServerHelloDone directly after ServerHello, so the handshake continued to tls.createClientKeyExchange(), which reads c.session.serverCertificate.publicKey and throws a TypeError on the null certificate. The exception propagates out of connection.process() without calling the verify or error callbacks.
There is no authentication bypass: without a server certificate the client cannot build its RSA key exchange, so the handshake cannot complete.
The fix reads c.session.serverCertificate and always fails the handshake in that case, still calling verify so the application can customize the alert. Failing even when verify returns true is needed because the key exchange requires the certificate.
Patches
Fixed in node-forge 1.4.1. The TLS client fails the handshake with an insufficient_security alert when the server sends no certificate.
Workarounds
Catch exceptions thrown by connection.process() in the code that feeds it network data, and close the connection when one occurs.
Credits
Reported by @arpitjain099.
Proof of concept
Connect a forge TLS client (forge.tls.createConnection({server: false, ...})) to a server whose first flight contains ServerHello and ServerHelloDone but no Certificate message. For example, run a forge TLS server and remove the Certificate handshake message (type 11) from its first flight before passing it to the client's process().
On 1.4.0 the client's process() throws "TypeError: Cannot read properties of null (reading 'publicKey')", and the verify and error callbacks are not called. On 1.4.1 the client calls verify with insufficient_security and no certificates, calls error with "No server certificate provided. Not enough security.", sends a fatal alert and closes the connection.
Regression tests are in tests/unit/tls.js ("missing server certificate").
Impact
Applications that use the forge TLS client (forge.tls.createConnection with server: false) are affected. A malicious server the application connects to, or an on-path attacker who can modify the unauthenticated handshake, can make the client throw from connection.process(). Since process() is normally called from a socket data handler, the uncaught exception terminates a Node.js process. There is no confidentiality or integrity impact. Applications using Node.js's own TLS implementation are not affected.
Inside the record
Evidence available
Describes the evidence in this view, not whether the product is safe.
Original records
CVE-2026-118778View the latest unmodified CVE JSON from the official source. It may be newer than this imported page.
cve.new JSON →Underlying weaknesses
The source’s classification of what caused the vulnerability.
Contributing organizations · 1
Assigning organization
What changed
Follow changesLarge field values are marked as truncated previews. Original source snapshots remain retained.