CVE-2026-119191 is a high-severity (CVSS 7.5) Uncontrolled Resource Consumption vulnerability in node-forge. A fix is available for node-forge — see the affected versions and patch details below.
Forge: ASN.1 resource exhaustion via BIT STRING decoding in asn1.fromDer
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-119191.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
Where this sits among everything scored
Real-World Exposure
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.
node-forgenpmDescription
Summary
asn1.fromDer() decodes the contents of BIT STRINGs as ASN.1 by default. That decode ignored the maxDepth recursion limit (an incomplete fix of CVE-2025-66031) and also decoded nested BIT STRINGs, keeping a full copy of the decoded contents at each level, so small crafted DER or PEM inputs (certificates, keys, PKCS structures) use excessive CPU time and memory and can abort the Node.js process. Fixed in node-forge 1.4.1.
Details
asn1.fromDer() attempts by default to decode the contents of primitive BIT STRINGs as ASN.1 (decodeBitStrings, default true). Two flaws in that decode in lib/asn1.js allow resource exhaustion:
_fromDer()started the BIT STRING decode with a new options object,{strict: true, decodeBitStrings: true}, that did not includemaxDepth. Inside that decode the depth check compared againstundefinedand never triggered, so the recursion limit added for CVE-2025-66031 (GHSA-554w-wpv2-vw27) was not enforced for anything below a decoded BIT STRING. Both the globalasn1.maxDepth(default 256) and the per-callmaxDepthoption were ignored there. Errors in this speculative decode, including stack overflows, are caught and the contents kept as raw bytes, so deep nesting is parsed instead of rejected. This is an incomplete fix of CVE-2025-66031.- BIT STRINGs nested inside decoded BIT STRING contents were decoded as well, and
asn1.create()gives each decoded BIT STRING a deep copy of its decoded contents (obj.original, used bytoDer()to detect changes). Memory use therefore grows quadratically with the nesting depth, even within the default depth limit.
No specification is violated; the parser lacks a resource limit.
The fix passes maxDepth to the BIT STRING decode, and decodes BIT STRING contents with decodeBitStrings: false, so only one level of BIT STRING contents is decoded. Contents that would exceed the limit, and BIT STRINGs inside decoded BIT STRING contents, are kept as undecoded BIT STRING values; toDer() writes their original bytes. Common structures such as SubjectPublicKeyInfo only use one level. Code that relied on nested decoding can decode the inner value explicitly with asn1.fromDer().
Patches
Fixed in node-forge 1.4.1. The maxDepth limit now applies to ASN.1 decoded from BIT STRING contents, and only one level of BIT STRING contents is decoded.
Workarounds
Code that calls forge.asn1.fromDer() directly and does not need encapsulated BIT STRING contents decoded can pass {decodeBitStrings: false}. This changes the parsed structure. The higher-level PKI, PKCS and TLS APIs do not expose this option and rely on the decoded form. For those, the only remedy is upgrading.
References
- CVE-2025-66031 / https://github.com/digitalbazaar/forge/security/advisories/GHSA-554w-wpv2-vw27 (ASN.1 Unbounded Recursion, fixed in 1.3.2)
- https://cwe.mitre.org/data/definitions/674.html (CWE-674: Uncontrolled Recursion)
- https://cwe.mitre.org/data/definitions/400.html (CWE-400: Uncontrolled Resource Consumption)
Severity
CVSS 3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (7.5, High) CVSS 4.0 (informational): CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N (8.7) Both versions rate this High. The severity rating follows CVSS 3.1.
Credits
Reported by Ethan Kim (cremit.io), Youngjoon Kim (@acorn421) and Brian Lee (@hibrian827) of Georgia Tech SSLab, @arpitjain099, and Mike Read.
Proof of concept
Input shape: n nested primitive BIT STRINGs (03 <len> 00 <inner>) around a NULL. For example:
var asn1 = forge.asn1;
var obj = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '');
for(var i = 0; i < 2000; ++i) {
obj = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, [obj]);
}
var der = asn1.toDer(obj).getBytes(); // 9,886 bytes
asn1.fromDer(der, {maxDepth: 10});
On 1.4.0 (Node.js 24) this parses all 2,000 levels despite maxDepth: 10, taking about 0.5-1 s and 600 MB. One SEQUENCE holding 20 such chains (about 198 KB) aborts a process with the default heap with "FATAL ERROR: JavaScript heap out of memory", which the application cannot catch. Within the depth limit, 80 chains of 254 levels (92 KB) still use about 0.8 GB. The same inputs wrapped as PEM reach pki.publicKeyFromPem() and pki.certificateFromPem() (a 20 KB certificate PEM used 1.3 GB before being rejected). On 1.4.1 these inputs parse in a few milliseconds and about 55-65 MB.
Regression tests in tests/unit/asn1.js: "should limit depth in decoded BIT STRINGs (default)", "should limit depth in decoded BIT STRINGs (maxDepth)", "should only decode one level of BIT STRINGs" and "should not decode BIT STRINGs in many BIT STRINGs".
Impact
A remote, unauthenticated attacker can supply a small DER or PEM structure with nested BIT STRINGs to any API that parses with asn1.fromDer() using default options. This includes pki.certificateFromPem(), pki.publicKeyFromPem(), the PKCS#7, PKCS#8 and PKCS#12 loaders, and server certificates received by forge's TLS client. Parsing such input consumes excessive CPU time and memory before the structure is rejected. On Node.js 24 a 10 KB input used about 600 MB and a 25 KB input about 1.4 GB. Inputs of about 25 KB abort a process limited to a 512 MB heap, and about 200 KB abort a process with the default heap, with a fatal out-of-memory error that the application cannot catch. Inputs that stay within the depth limit still reach about 0.8 GB at 92 KB and 1.8 GB at 231 KB. The result is denial of service. There is no confidentiality or integrity impact.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | node-forge | all versions | 1.4.1npm install node-forge@1.4.1 |
Affected Products
forgedigitalbazaarDetection & mitigation playbook
Open-source dependencyDetect
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.
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-119191 is resolved across your whole dependency graph.
Workarounds
Stop feeding it untrusted input: reject or quarantine files and payloads from unverified sources until you can upgrade, restrict accepted formats to the ones you actually need, and run the parsing or decoding step in a least-privileged sandbox or short-lived worker so a crash or corrupted read cannot reach the rest of the process.
Fixing This On Your OS
If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.
--- CME Mitigation Guidance (2026-11-06) --- Disclaimer: The following mitigation solutions are provided as a courtesy, pending the application of an official patch. This content was generated utilizing AI tools in conjunction with data from https://cmetaxonomy.org. Customers are advised to independently evaluate and test these temporary mitigations within their own infrastructure. The highest-value action is to enforce recursion depth limits and disable nested BIT STRING decoding during ASN.1 parsing in node-forge: upgrade to node-forge 1.4.1 (or the corresponding fixed Red Hat builds), which propagate maxDepth into recursive subOptions and set decodeBitStrings to false so only one level…Source: Red Hat security advisory for CVE-2026-119191 (CC BY 4.0)
Frequently Asked Questions
Is CVE-2026-119191 in your dependencies?
Find it across npm, including transitive dependencies.