{"id":"EUVD-2026-113347","revision":null,"records":[{"revision":"f1505b008b394b95b61818499e399663","observedAt":"2026-10-29T21:48:56.968+00:00","statement":{"source":"cve-program","id":"CVE-2026-119190","aliases":[],"title":"Forge: X.509 basicConstraints bypass in verifyCertificateChain() via deprecated extension OIDs 2.5.29.10 and 2.5.29.13","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, node-forge parsed deprecated extension OIDs 2.5.29.10 and 2.5.29.13 as basicConstraints, and pki.verifyCertificateChain() used the first extension with that name. Exploitation requires a CA trusted by the application to issue a certificate carrying an attacker-supplied deprecated-OID extension, commonly because the CA copies extensions from a certificate signing request. By placing a permissive deprecated extension before the genuine 2.5.29.19 basicConstraints extension, the certificate holder could have the certificate accepted as a CA and issue certificates for arbitrary names, enabling server or client impersonation. If the issuing CA adds a keyUsage extension without keyCertSign, node-forge rejects the chain. This issue is fixed in version 1.4.1.","state":0,"publishedAt":"2026-10-29T19:25:09.677+00:00","modifiedAt":"2026-10-29T20:25:04.131+00:00","affected":[{"ecosystem":"Vendor product","name":"forge","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"digitalbazaar\",\n                    \"product\": \"forge\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 1.4.1\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","score":7.4,"severity":"HIGH"}],"references":["https://github.com/digitalbazaar/forge/security/advisories/GHSA-5x38-2vff-x55p","https://github.com/digitalbazaar/forge/commit/58c06bc251856b409c30ecb35a93f5f6c9bbc84a","https://github.com/digitalbazaar/forge/releases/tag/v1.4.1"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-119190","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-119190","identifiers":["CVE-2026-119190"]},"retained":false,"historicalAffected":[]},{"revision":"6fa4dc1fe9b04f36a48b07d40dd8d4d8","observedAt":"2026-11-06T01:44:42.768+00:00","statement":{"source":"euvd","id":"EUVD-2026-113347","aliases":["CVE-2026-119190","GHSA-5x38-2vff-x55p"],"title":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, node-forge parsed deprecated extension OIDs 2.5.29.10 and 2.5.29.13 as basicConstraints, and pki.verifyCertificateChain() u…","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, node-forge parsed deprecated extension OIDs 2.5.29.10 and 2.5.29.13 as basicConstraints, and pki.verifyCertificateChain() used the first extension with that name. Exploitation requires a CA trusted by the application to issue a certificate carrying an attacker-supplied deprecated-OID extension, commonly because the CA copies extensions from a certificate signing request. By placing a permissive deprecated extension before the genuine 2.5.29.19 basicConstraints extension, the certificate holder could have the certificate accepted as a CA and issue certificates for arbitrary names, enabling server or client impersonation. If the issuing CA adds a keyUsage extension without keyCertSign, node-forge rejects the chain. This issue is fixed in version 1.4.1.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","score":7.4,"severity":null}],"references":["https://github.com/digitalbazaar/forge/security/advisories/GHSA-5x38-2vff-x55p","https://github.com/digitalbazaar/forge/commit/58c06bc251856b409c30ecb35a93f5f6c9bbc84a","https://github.com/digitalbazaar/forge/releases/tag/v1.4.1"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-113347","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Oct 29, 2026, 7:25:09 PM","dateUpdated":"Oct 29, 2026, 8:25:04 PM"},"relatedAdvisories":[{"id":"msrc_CVE-2026-119190","title":"Forge: X.509 basicConstraints bypass in verifyCertificateChain() via deprecated extension OIDs 2.5.29.10 and 2.5.29.13","vulnerabilityIds":["CVE-2026-119190"]}],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-113347","identifiers":["EUVD-2026-113347","CVE-2026-119190","GHSA-5x38-2vff-x55p"]},"retained":false,"historicalAffected":[]},{"revision":"54532eb360784cb6889540a16dfe4582","observedAt":"2026-10-30T23:47:40.018+00:00","statement":{"source":"nvd","id":"CVE-2026-119190","aliases":[],"title":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, node-forge parsed deprecated extension OIDs 2.5.29.10 and 2.5.29.13 as basicConstraints, and pki.verifyCertificateChain() u…","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, node-forge parsed deprecated extension OIDs 2.5.29.10 and 2.5.29.13 as basicConstraints, and pki.verifyCertificateChain() used the first extension with that name. Exploitation requires a CA trusted by the application to issue a certificate carrying an attacker-supplied deprecated-OID extension, commonly because the CA copies extensions from a certificate signing request. By placing a permissive deprecated extension before the genuine 2.5.29.19 basicConstraints extension, the certificate holder could have the certificate accepted as a CA and issue certificates for arbitrary names, enabling server or client impersonation. If the issuing CA adds a keyUsage extension without keyCertSign, node-forge rejects the chain. This issue is fixed in version 1.4.1.","state":0,"publishedAt":"2026-10-29T20:17:30.067+00:00","modifiedAt":"2026-10-30T17:18:03.88+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","score":7.4,"severity":"HIGH"}],"references":["https://github.com/digitalbazaar/forge/commit/58c06bc251856b409c30ecb35a93f5f6c9bbc84a","https://github.com/digitalbazaar/forge/releases/tag/v1.4.1","https://github.com/digitalbazaar/forge/security/advisories/GHSA-5x38-2vff-x55p"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-119190","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Undergoing Analysis","weaknesses":["CWE-295","CWE-436"],"productCriteria":[],"sourceDates":{"published":"2026-10-29T20:17:30.067","lastModified":"2026-10-30T17:18:03.880"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-119190","identifiers":["CVE-2026-119190"]},"retained":false,"historicalAffected":[]},{"revision":"bd884a33afc746d59dd35a8ff6279e50","observedAt":"2026-10-30T23:45:44.41+00:00","statement":{"source":"osv","id":"GHSA-5x38-2vff-x55p","aliases":["CVE-2026-119190"],"title":"Forge: X.509 basicConstraints bypass in verifyCertificateChain() via deprecated extension OIDs 2.5.29.10 and 2.5.29.13","description":"### Summary\nnode-forge parses certificate extensions with the deprecated OIDs `2.5.29.10` and `2.5.29.13` as `basicConstraints`, and `forge.pki.verifyCertificateChain()` used the first extension with that name. A certificate with a forged deprecated-OID extension (`cA` TRUE) before its genuine `basicConstraints` extension (`cA` FALSE) is accepted as a CA certificate, and the same technique can hide a `pathLenConstraint`. Fixed in node-forge 1.4.1.\n\n### Details\n`lib/oids.js` maps the deprecated certificate extension OIDs `2.5.29.10` and `2.5.29.13` to the name `basicConstraints`, the same name as the RFC 5280 extension `2.5.29.19`. `certificateExtensionFromAsn1()` in `lib/x509.js` decodes extensions by name, so these extensions are decoded into the same `cA` and `pathLenConstraint` fields. `cert.getExtension()` returns the first extension with a matching name, and `pki.verifyCertificateChain()` looked up `basicConstraints` by name.\n\nAs a result, a certificate that contains a `2.5.29.10` (or `2.5.29.13`) extension with `cA` TRUE before its genuine `basicConstraints` extension with `cA` FALSE is accepted as a CA certificate. The same technique can hide a CA certificate's `pathLenConstraint`. A deprecated-OID extension on its own also satisfies the check added for GHSA-2328-f5f3-gj25 (CVE-2026-33896) that `basicConstraints` is present. RFC 5280 section 4.2.1.9 defines basicConstraints only as `id-ce 19` (`2.5.29.19`), and the path validation checks in section 6.1.4 apply to that extension.\n\nThe fix makes chain verification look up basicConstraints by OID (`cert.getExtension({id: '2.5.29.19'})`). This covers both the `cA` and the `pathLenConstraint` checks. Certificate parsing, the OID table and `cert.getExtension('basicConstraints')` are unchanged.\n\n#### Patches\nFixed in node-forge 1.4.1. Chain verification now uses only the `basicConstraints` extension with OID `2.5.29.19`.\n\n#### Workarounds\nNone in node-forge itself. Applications that pass an `options.verify` callback to `pki.verifyCertificateChain()` (or `verify` to `forge.tls.createConnection()`) can reject chains in which a non-leaf certificate has no `2.5.29.19` extension with `cA` TRUE, for example with `cert.getExtension({id: '2.5.29.19'})`. CA operators can avoid copying unrecognized extensions from certificate requests.\n\n#### Credits\n\nWorkOS Security Team· [security@workos.com](mailto:security@workos.com) (@nickcollisson-workos)\n\n### Proof of concept\nHave a trusted CA issue an end-entity certificate whose extensions are, in this order: a `2.5.29.10` (or `2.5.29.13`) extension with the value of a basicConstraints `cA` TRUE (DER `30 03 01 01 FF`), then the CA's own `2.5.29.19` basicConstraints with `cA` FALSE, and no `keyUsage`. For example, `openssl x509 -req -copy_extensions copy` with an extensions file that sets `basicConstraints = CA:FALSE` copies the extension from the CSR and produces this order. Use that certificate's key to sign a leaf certificate for any name.\n\nOn node-forge <= 1.4.0, `forge.pki.verifyCertificateChain(caStore, [leaf, eeCert])` accepts the chain, and `eeCert.getExtension('basicConstraints')` returns the `2.5.29.10` extension with `cA` true. The same certificate without the deprecated-OID extension is rejected (\"Certificate basicConstraints indicates the certificate is not a CA.\"). A certificate with only the deprecated-OID extension is also accepted.\n\nThe fix adds regression tests in `tests/unit/x509.js` and the reporter's PoC as `tests/pocs/ghsa-5x38-2vff-x55p.js`.\n\n### Impact\nApplications that verify certificate chains with `forge.pki.verifyCertificateChain()`, including TLS peer certificate verification in `forge.tls`, are affected.\n\nExploitation requires a CA trusted by the application to issue a certificate that contains the attacker-supplied deprecated-OID extension, typically a CA that copies extensions from certificate signing requests. For example, `openssl x509 -req -copy_extensions copy` (or `copyall`) with an extensions file that sets `basicConstraints = CA:FALSE` and no `keyUsage` produces such a certificate. If the issuing CA adds a `keyUsage` extension without `keyCertSign`, node-forge rejects the chain.\n\nThe holder of such a certificate can then issue certificates for any name that `pki.verifyCertificateChain()` accepts. In forge's own TLS stack this allows impersonating servers (or clients, where client certificates are verified) and intercepting traffic.","state":0,"publishedAt":"2026-10-30T23:01:46+00:00","modifiedAt":"2026-10-30T23:15:08.0805867+00:00","affected":[{"ecosystem":"npm","name":"node-forge","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"1.4.1"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/digitalbazaar/forge/security/advisories/GHSA-5x38-2vff-x55p","https://nvd.nist.gov/vuln/detail/CVE-2026-119190","https://github.com/digitalbazaar/forge/commit/58c06bc251856b409c30ecb35a93f5f6c9bbc84a","https://github.com/digitalbazaar/forge","https://github.com/digitalbazaar/forge/releases/tag/v1.4.1"],"sourceUrl":"https://github.com/advisories/GHSA-5x38-2vff-x55p","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-5x38-2vff-x55p","identifiers":["GHSA-5x38-2vff-x55p","CVE-2026-119190"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-07T02:34:43.7661215+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-07T02:34:43.7661215+00:00","lastSuccessAt":"2026-11-07T02:34:43.9387828+00:00","error":null,"lastVerifiedAt":"2026-11-07T02:34:43.9387838+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-bb5c9d5a08063ef076042e33dd72a7d0ffa4c4487efdcf3106e29ba55ec2ad57-5aac302c22044f92cc2d766b3e31e7dc718ccd14d0209c666b12bbe38c20772f","complete":true,"records":420475,"lastAttemptAt":"2026-11-07T02:34:42.7079446+00:00","lastSuccessAt":"2026-11-07T02:34:42.70025+00:00","error":null,"lastVerifiedAt":"2026-11-07T02:34:42.7079446+00:00","snapshotPublishedAt":"2026-11-07T01:31:15+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-b8d16fbf74464bc88a41c5137fa81682","complete":false,"records":13623,"lastAttemptAt":"2026-11-07T02:46:32.0890109+00:00","lastSuccessAt":"2026-11-07T02:46:32.084+00:00","error":"11 identifier lookups failed; latest failures include HTTP 403. Other identifiers were checked independently.","lastVerifiedAt":"2026-11-07T02:46:32.084+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13674,"expectedIdentifiers":13685,"failedIdentifiers":11},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-07T02:34:43.7661215+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-07T02:34:43.7661215+00:00","lastSuccessAt":"2026-11-07T02:34:43.9397262+00:00","error":null,"lastVerifiedAt":"2026-11-07T02:34:43.9397266+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-34343b4ea57e47c5a482c8fcf20a381e","complete":true,"records":13645,"lastAttemptAt":"2026-11-07T02:34:44.5754579+00:00","lastSuccessAt":"2026-11-07T01:26:55.938+00:00","error":null,"lastVerifiedAt":"2026-11-07T01:26:55.938+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-0eb4d6dde62dffacd040ad992d4fd5a65cd7d0dc5f5f4cfa8b41967fc6f9ca5f","complete":true,"records":9914,"lastAttemptAt":"2026-11-07T02:34:43.3341619+00:00","lastSuccessAt":"2026-11-06T20:10:36.6450506+00:00","error":null,"lastVerifiedAt":"2026-11-07T02:34:43.3341619+00:00","snapshotPublishedAt":"2026-11-06T20:02:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-fde804134ecdda0ddd5ff5c26ee1fff5a6fa659311f7ef2e51c6ad54964db0e2","complete":true,"records":1971,"lastAttemptAt":"2026-11-07T02:34:42.8444254+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-07T02:34:42.8444254+00:00","snapshotPublishedAt":"2026-11-06T18:17:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-335633e78a15c9cde10a6025895b5617717087fb945489ae7e15d377bacf34a9","complete":true,"records":3055,"lastAttemptAt":"2026-11-07T02:34:43.7181027+00:00","lastSuccessAt":"2026-11-06T16:03:00.7615789+00:00","error":null,"lastVerifiedAt":"2026-11-07T02:34:43.7181027+00:00","snapshotPublishedAt":"2026-11-06T16:02:48+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-a0b728bc1c5526b5429930c00621636eba8655069c176697c3080f8377619ad7","complete":true,"records":231291,"lastAttemptAt":"2026-11-07T02:34:43.2326712+00:00","lastSuccessAt":"2026-11-07T00:28:51.1983528+00:00","error":null,"lastVerifiedAt":"2026-11-07T02:34:43.2326712+00:00","snapshotPublishedAt":"2026-11-06T23:33:08+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}