CVE-2026-118780
Forge: verifyCertificateChain() removes trusted CA certificates with the same subject from the CA store
Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used pki.verifyCertificateChain(), pki.createCaStore(), duplicate subject names to process the relevant input or security decision. node-forge modified the CA store while trying certificates that shared a subject name during pki.verifyCertificateChain(). A failed chain verification could permanently remove trusted CA certificates from the store, causing later valid chains to fail and creating a persistent availability impact for applications that reused the store. This issue is fixed in version 1.4.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
3.7
Forge: verifyCertificateChain() removes trusted CA certificates with the same subject from the CA store
Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used pki.verifyCertificateChain(), pki.createCaStore(), duplicate subject names to process the relevant input or security decision. node-forge modified the CA store while trying certificates that shared a subject name during pki.verifyCertificateChain(). A failed chain verification could permanently remove trusted CA certificates from the store, causing later valid chains to fail and creating a persistent availability impact for applications that reused the store. This issue is fixed in version 1.4.1.
- Record
CVE-2026-118780- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-295, CWE-471
- Updated
- 2026-11-04
EUVDEUVD-2026-113338
3.7
Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used pki.verifyCertificateChain(), pki.createCaStore(), duplicate subject names to process the relevant input or security decision. node-forge modified the CA store while trying certificates that shared a subject name during pki.verifyCertificateChain(). A failed chain verification could permanently remove trusted CA certificates from the store, causing later valid chains to fail and creating a persistent availability impact for applications that reused the store. This issue is fixed in version 1.4.1.
- Record
EUVD-2026-113338- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-04
GitHub AdvisoriesGHSA-4487-j8r4-4g2f
3.7
Forge: verifyCertificateChain() removes trusted CA certificates with the same subject from the CA store
Summary
When a CA store created by pki.createCaStore() holds two or more certificates with the same subject name, pki.verifyCertificateChain() permanently removes those certificates from the store while trying each one as the issuer. A peer can send any certificate that names that subject as its issuer to make all later verifications against those CA certificates fail. Fixed in node-forge 1.4.1.
Details
pki.verifyCertificateChain() (lib/x509.js) asks the CA store for the issuer of each certificate with caStore.getIssuer(). When the store holds several certificates with the same subject, caStore.getIssuer() returns the store's own internal array of those certificates (caStore.certs[hash], built by addCertificate()). verifyCertificateChain() used that array directly as its list of candidate parents and called parents.shift() on it while trying each candidate. Every candidate it tried, including the one that finally verified the certificate, was removed from the store.
Once the array is empty, getIssuer() returns an empty list, no candidate is tried, and verification fails with "Certificate signature is invalid." hasCertificate() and listAllCertificates() no longer see the removed certificates. The store stays in this state for as long as the object is used.
The attacker's certificate only needs an issuer name equal to the shared subject name, which is public. Its signature and key can be arbitrary: every candidate is tried and shifted out because none verifies, and errors from parent.verify() are caught by the loop. Verification of the attacker's chain fails as expected. Verifying valid chains has a similar effect: the CA certificate that verified the chain and any tried before it are removed.
No chain is accepted that should be rejected. Removing candidates can only turn a success into a failure.
RFC 5280, Section 6.1.1(d) treats trust anchor information as an input to path validation. Validation should not consume it.
The fix copies the array returned by getIssuer() before iterating over it, so the CA store is no longer modified. getIssuer() itself is unchanged.
Patches
Fixed in node-forge 1.4.1. pki.verifyCertificateChain() now works on a copy of the candidate issuer list instead of shifting entries out of the CA store.
Workarounds
-
Pass a fresh CA store to each
pki.verifyCertificateChain()call (for examplepki.createCaStore(trustedCerts)), or passcaStoretoforge.tls.createConnection()as an array of certificates instead of a store object, so that forge creates a new store per connection. -
Or wrap the store so that
getIssuer()returns a copy:var getIssuer = caStore.getIssuer; caStore.getIssuer = function(cert) { var r = getIssuer(cert); return Array.isArray(r) ? r.slice() : r; };
Proof of concept
Two trusted self-signed CA certificates, rootA and rootB, share the subject CN=Root. bogus is any certificate whose issuer is CN=Root, signed with an unrelated key. leafA is a valid certificate issued by rootA.
var caStore = forge.pki.createCaStore([rootA, rootB]);
caStore.listAllCertificates().length; // 2
try { forge.pki.verifyCertificateChain(caStore, [bogus]); } catch(e) {}
// rejected as expected ("Certificate signature is invalid.")
caStore.listAllCertificates().length; // 0: both CA certificates are gone
forge.pki.verifyCertificateChain(caStore, [leafA]);
// throws "Certificate signature is invalid." (valid chain now rejected)
Without the attacker certificate, verifying leafA twice against a fresh store gives the same result: the first call succeeds and removes rootA, the second fails. With the fix, the store keeps both certificates and every valid chain verifies. The regression tests are in tests/unit/x509.js ("CA store" section).
Impact
Applications that keep a long-lived CA store holding several trusted certificates with the same subject name, and…
- Record
GHSA-4487-j8r4-4g2f- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-295, CWE-471
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-gf8q-jrpm-jvxq No score
URL parsing in node-forge could lead to undesired behavior.
Impact
The regex used for the forge.util.parseUrl API would not properly parse certain inputs resulting in a parsed data structure that could lead to undesired behavior.
Patches
forge.util.parseUrl and other very old related URL APIs were removed in 1.0.0 in favor of letting applications use the more modern WHATWG URL Standard API.
Workarounds
Ensure code does not directly or indirectly call forge.util.parseUrl with untrusted input.
References
For more information
If you have any questions or comments about this advisory:
- Open an issue in forge
- Email us at [email protected]
- Record
GHSA-gf8q-jrpm-jvxq- Weakness
- CWE-601
- Updated
- 2026-11-02
NVD
3.7
Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used pki.verifyCertificateChain(), pki.createCaStore(), duplicate subject names to process the relevant input or security decision. node-forge modified the CA store while trying certificates that shared a subject name during pki.verifyCertificateChain(). A failed chain verification could permanently remove trusted CA certificates from the store, causing later valid chains to fail and creating a persistent availability impact for applications that reused the store. This issue is fixed in version 1.4.1.
- Record
CVE-2026-118780- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-295, CWE-471
- Updated
- 2026-11-04
OSV
3.7
Forge: verifyCertificateChain() removes trusted CA certificates with the same subject from the CA store
Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used pki.verifyCertificateChain(), pki.createCaStore(), duplicate subject names to process the relevant input or security decision. node-forge modified the CA store while trying certificates that shared a subject name during pki.verifyCertificateChain(). A failed chain verification could permanently remove trusted CA certificates from the store, causing later valid chains to fail and creating a persistent availability impact for applications that reused the store. This issue is fixed in version 1.4.1.
- Record
CVE-2026-118780- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-295, CWE-471
- Updated
- 2026-11-07
Show 9 moreShow less
OSVGHSA-4487-j8r4-4g2f
3.7
Forge: verifyCertificateChain() removes trusted CA certificates with the same subject from the CA store
Summary
When a CA store created by pki.createCaStore() holds two or more certificates with the same subject name, pki.verifyCertificateChain() permanently removes those certificates from the store while trying each one as the issuer. A peer can send any certificate that names that subject as its issuer to make all later verifications against those CA certificates fail. Fixed in node-forge 1.4.1.
Details
pki.verifyCertificateChain() (lib/x509.js) asks the CA store for the issuer of each certificate with caStore.getIssuer(). When the store holds several certificates with the same subject, caStore.getIssuer() returns the store's own internal array of those certificates (caStore.certs[hash], built by addCertificate()). verifyCertificateChain() used that array directly as its list of candidate parents and called parents.shift() on it while trying each candidate. Every candidate it tried, including the one that finally verified the certificate, was removed from the store.
Once the array is empty, getIssuer() returns an empty list, no candidate is tried, and verification fails with "Certificate signature is invalid." hasCertificate() and listAllCertificates() no longer see the removed certificates. The store stays in this state for as long as the object is used.
The attacker's certificate only needs an issuer name equal to the shared subject name, which is public. Its signature and key can be arbitrary: every candidate is tried and shifted out because none verifies, and errors from parent.verify() are caught by the loop. Verification of the attacker's chain fails as expected. Verifying valid chains has a similar effect: the CA certificate that verified the chain and any tried before it are removed.
No chain is accepted that should be rejected. Removing candidates can only turn a success into a failure.
RFC 5280, Section 6.1.1(d) treats trust anchor information as an input to path validation. Validation should not consume it.
The fix copies the array returned by getIssuer() before iterating over it, so the CA store is no longer modified. getIssuer() itself is unchanged.
Patches
Fixed in node-forge 1.4.1. pki.verifyCertificateChain() now works on a copy of the candidate issuer list instead of shifting entries out of the CA store.
Workarounds
-
Pass a fresh CA store to each
pki.verifyCertificateChain()call (for examplepki.createCaStore(trustedCerts)), or passcaStoretoforge.tls.createConnection()as an array of certificates instead of a store object, so that forge creates a new store per connection. -
Or wrap the store so that
getIssuer()returns a copy:var getIssuer = caStore.getIssuer; caStore.getIssuer = function(cert) { var r = getIssuer(cert); return Array.isArray(r) ? r.slice() : r; };
Proof of concept
Two trusted self-signed CA certificates, rootA and rootB, share the subject CN=Root. bogus is any certificate whose issuer is CN=Root, signed with an unrelated key. leafA is a valid certificate issued by rootA.
var caStore = forge.pki.createCaStore([rootA, rootB]);
caStore.listAllCertificates().length; // 2
try { forge.pki.verifyCertificateChain(caStore, [bogus]); } catch(e) {}
// rejected as expected ("Certificate signature is invalid.")
caStore.listAllCertificates().length; // 0: both CA certificates are gone
forge.pki.verifyCertificateChain(caStore, [leafA]);
// throws "Certificate signature is invalid." (valid chain now rejected)
Without the attacker certificate, verifying leafA twice against a fresh store gives the same result: the first call succeeds and removes rootA, the second fails. With the fix, the store keeps both certificates and every valid chain verifies. The regression tests are in tests/unit/x509.js ("CA store" section).
Impact
Applications that keep a long-lived CA store holding several trusted certificates with the same subject name, and…
- Record
GHSA-4487-j8r4-4g2f- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-295, CWE-471
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-118780
3.7
Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used pki.verifyCertificateChain(), pki.createCaStore(), duplicate subject names to process the relevant input or security decision. node-forge modified the CA store while trying certificates that shared a subject name during pki.verifyCertificateChain(). A failed chain verification could permanently remove trusted CA certificates from the store, causing later valid chains to fail and creating a persistent availability impact for applications that reused the store. This issue is fixed in version 1.4.1.
- Record
UBUNTU-CVE-2026-118780- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-05
OSVAZL-112490 No score
CVE-2026-118780 affecting package python-tensorboard 2.16.2-6
Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used pki.verifyCertificateChain(), pki.createCaStore(), duplicate subject names to process the relevant input or security decision. node-forge modified the CA store while trying certificates that shared a subject name during pki.verifyCertificateChain(). A failed chain verification could permanently remove trusted CA certificates from the store, causing later valid chains to fail and creating a persistent availability impact for applications that reused the store. This issue is fixed in version 1.4.1.
- Record
AZL-112490- Updated
- 2026-11-05
OSVCLSA-2026-1793790288 No score
TuxCare security update for node-forge (10 CVEs)
TuxCare rebuilt node-forge to address 10 CVEs. Fixed in 1.3.3-tuxcare.3.
- Record
CLSA-2026-1793790288- Updated
- 2026-11-04
OSVCLSA-2026-1793801784 No score
TuxCare security update for node-forge (6 CVEs)
TuxCare rebuilt node-forge to address 6 CVEs. Fixed in 1.3.1-tuxcare.2.
- Record
CLSA-2026-1793801784- Updated
- 2026-11-04
OSVCLSA-2026-1793808759 No score
TuxCare security update for node-forge (6 CVEs)
TuxCare rebuilt node-forge to address 6 CVEs. Fixed in 0.10.0-tuxcare.8.
- Record
CLSA-2026-1793808759- Updated
- 2026-11-04
OSVCLSA-2026-1793814373 No score
TuxCare security update for node-forge (8 CVEs)
TuxCare rebuilt node-forge to address 8 CVEs. Fixed in 0.9.0-tuxcare.1.
- Record
CLSA-2026-1793814373- Updated
- 2026-11-05
OSVGHSA-gf8q-jrpm-jvxq No score
URL parsing in node-forge could lead to undesired behavior.
Impact
The regex used for the forge.util.parseUrl API would not properly parse certain inputs resulting in a parsed data structure that could lead to undesired behavior.
Patches
forge.util.parseUrl and other very old related URL APIs were removed in 1.0.0 in favor of letting applications use the more modern WHATWG URL Standard API.
Workarounds
Ensure code does not directly or indirectly call forge.util.parseUrl with untrusted input.
References
For more information
If you have any questions or comments about this advisory:
- Open an issue in forge
- Email us at [email protected]
- Record
GHSA-gf8q-jrpm-jvxq- Weakness
- CWE-601
- Updated
- 2026-11-02
OSVROOT-APP-NPM-GHSA-gf8q-jrpm-jvxq No score
GHSA-gf8q-jrpm-jvxq in node-forge - Patched by Root
Root has patched GHSA-gf8q-jrpm-jvxq in the node-forge package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-GHSA-gf8q-jrpm-jvxq- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
node-forgenpm |
through 1.4.0 | 1.4.1 |
node-forgenpm |
before 1.0.0 | 1.0.0 |
python-tensorboardAzure Linux:3 |
through 2.16.2-6 | None known |
node-forgeTuxCare:npm From an advisory covering 10 CVEs |
1.3.3-tuxcare.0 up to 1.3.3-tuxcare.3, plus listed versions 1.3.31.3.3-tuxcare.11.3.3-tuxcare.2 |
1.3.3-tuxcare.3 |
node-forgeTuxCare:npm From an advisory covering 6 CVEs |
1.3.1-tuxcare.0 up to 1.3.1-tuxcare.2, plus listed versions 1.3.11.3.1-tuxcare.1 |
1.3.1-tuxcare.2 |
node-forgeTuxCare:npm From an advisory covering 6 CVEs |
0.10.0-tuxcare.0 up to 0.10.0-tuxcare.8, plus listed versions 0.10.00.10.0-tuxcare.10.10.0-tuxcare.20.10.0-tuxcare.30.10.0-tuxcare.40.10.0-tuxcare.50.10.0-tuxcare.60.10.0-tuxcare.7 |
0.10.0-tuxcare.8 |
node-forgeTuxCare:npm From an advisory covering 7 CVEs |
0.9.0-tuxcare.0 up to 0.9.0-tuxcare.1, plus listed versions 0.9.0 |
0.9.0-tuxcare.1 |
node-forgenpm |
before 1.4.1 | 1.4.1 |
node-forgeRoot:npm |
before 1.0.0-aikido.1 | 1.0.0-aikido.1 |
@rootio/node-forgeRoot:npm |
before 1.0.0-root.io.1 | 1.0.0-root.io.1 |
node-node-forgeUbuntu:20.04:LTS |
All versions, plus listed versions 0.8.5~dfsg-20.9.1~dfsg-1 |
None known |
node-node-forgeUbuntu:22.04:LTS |
All versions, plus listed versions 0.10.0~dfsg-31.2.1~dfsg-2 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | OSV | |
| affected, aliases, cwes, published, references | OSV | |
| affected, aliases | OSV | |
| affected, aliases | EUVD, NVD, OSV | |
| facts, references | CVE List | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-118780 is a low vulnerability (CVSS 3.7) in Digitalbazaar Forge, published January 8, 2022. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.17%, the 6th percentile. Fixed in node-forge 1.4.1.
References
github.com/digitalbazaar/forge/security/advisories/GHSA-4487-j8r4-4g2f
github.com/digitalbazaar/forge/commit/f6555609bd30f442fbfacd543155928ceccf98d0
github.com/digitalbazaar/forge/releases/tag/v1.4.1
nvd.nist.gov/vuln/detail/CVE-2026-118780
github.com/advisories/GHSA-4487-j8r4-4g2f
github.com/digitalbazaar/forge/security/advisories/GHSA-gf8q-jrpm-jvxq
Show 7 moreShow less
nvd.nist.gov/vuln/detail/CVE-2022-0122
huntr.dev/bounties/41852c50-3c6d-4703-8c55-4db27164a4ae
github.com/advisories/GHSA-gf8q-jrpm-jvxq
github.com/CVEProject/cvelistV5/tree/main/cves/2026/118xxx/CVE-2026-118780.json
github.com/digitalbazaar/forge
ubuntu.com/security/CVE-2026-118780
cve.org/CVERecord?id=CVE-2026-118780
Left out here: the rest of 2 source descriptions. The JSON record has them.