{"id":"CVE-2026-118774","aliases":["AZL-112505","CLSA-2026-1794329081","CLSA-2026-1794330948","EUVD-2026-113331","GHSA-9wg5-mj3p-v49q","UBUNTU-CVE-2026-118774"],"status":"published","title":"Forge: Certificate signature verified with the issuer's RSA signature scheme","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used certificate.verify(child), _verifySignature(), lib/x509.js to process the relevant input or security decision. node-forge selected RSA padding and RSASSA-PSS parameters from the issuer certificate rather than the child certificate being verified. A child labeled as RSASSA-PSS could therefore be accepted with a PKCS#1 v1.5 signature when the issuer used PKCS#1 v1.5. The signature still had to be produced with the trusted issuer's private key, so this did not permit certificate identity forgery, but it could bypass policies that require a declared signature scheme. This issue is fixed in version 1.4.1.","severity":{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00103,"percentile":0.00986,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-347"],"published":"2026-10-29T18:33:46.399Z","modified":"2026-11-10T19:46:07Z","fixes":[{"ecosystem":"npm","package":"node-forge","fixed_in":["1.4.1"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"node-forge","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"1.4.0"},{"fixed":"1.4.1"}]}]},{"source":"osv","ecosystem":"Azure Linux:3","package":"python-tensorboard","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"2.16.2-6"}]}]},{"source":"osv","ecosystem":"TuxCare:npm","package":"node-forge","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.3.3-tuxcare.0"},{"fixed":"1.3.3-tuxcare.5"}]}],"versions":["1.3.3","1.3.3-tuxcare.1","1.3.3-tuxcare.2","1.3.3-tuxcare.3","1.3.3-tuxcare.4"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:npm","package":"node-forge","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.3.1-tuxcare.0"},{"fixed":"1.3.1-tuxcare.5"}]}],"versions":["1.3.1","1.3.1-tuxcare.1","1.3.1-tuxcare.2","1.3.1-tuxcare.3","1.3.1-tuxcare.4"],"bundled":2},{"source":"osv","ecosystem":"npm","package":"node-forge","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.4.1"}]}]},{"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"}],"references":[{"url":"https://github.com/digitalbazaar/forge/security/advisories/GHSA-9wg5-mj3p-v49q","tags":["x_refsource_CONFIRM","Exploit","Mitigation","Vendor Advisory","advisory","web","report"]},{"url":"https://github.com/digitalbazaar/forge/commit/c7f42614d5166a77ddf11ce174b2601b14f6956b","tags":["x_refsource_MISC","Patch","fix","web","report"]},{"url":"https://github.com/digitalbazaar/forge/releases/tag/v1.4.1","tags":["x_refsource_MISC","Release Notes","web","report"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-118774","tags":["web","advisory"]},{"url":"https://github.com/advisories/GHSA-9wg5-mj3p-v49q"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/118xxx/CVE-2026-118774.json","tags":["advisory"]},{"url":"https://github.com/digitalbazaar/forge","tags":["package"]},{"url":"https://ubuntu.com/security/CVE-2026-118774","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-118774","tags":["report"]}],"sources":{"cve":[{"id":"CVE-2026-118774","title":"Forge: Certificate signature verified with the issuer's RSA signature scheme","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used certificate.verify(child), _verifySignature(), lib/x509.js to process the relevant input or security decision. node-forge selected RSA padding and RSASSA-PSS parameters from the issuer certificate rather than the child certificate being verified. A child labeled as RSASSA-PSS could therefore be accepted with a PKCS#1 v1.5 signature when the issuer used PKCS#1 v1.5. The signature still had to be produced with the trusted issuer's private key, so this did not permit certificate identity forgery, but it could bypass policies that require a declared signature scheme. This issue is fixed in version 1.4.1.","status":"published","published":"2026-10-29T18:33:46.399Z","modified":"2026-11-03T16:17:21.117Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low","assessor":"cna"}],"cwes":["CWE-347"],"updated_at":"2026-11-03T17:29:02.209656Z"}],"euvd":[{"id":"EUVD-2026-113331","description":"Forge: Certificate signature verified with the issuer's RSA signature scheme","status":"published","published":"2026-11-10T15:57:48Z","modified":"2026-11-10T15:57:48Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"}],"updated_at":"2026-11-10T17:21:44.229469Z"}],"ghsa":[{"id":"GHSA-9wg5-mj3p-v49q","title":"Forge: Certificate signature verified with the issuer's RSA signature scheme","description":"### Summary\n\nWhen verifying a certificate, node-forge chose the RSA padding scheme (PKCS#1 v1.5 or RSASSA-PSS) and PSS parameters from the issuer certificate's own signature algorithm instead of the certificate being verified. A certificate labeled as signed with RSASSA-PSS could pass `verifyCertificateChain()` with a PKCS#1 v1.5 signature. Fixed in node-forge 1.4.1.\n\n### Details\n\n`certificate.verify(child)` in `lib/x509.js` hashes the child's TBSCertificate with the digest of the child's signature algorithm, then calls `_verifySignature()` with the issuer certificate. `_verifySignature()` selected the padding scheme from that certificate's `signatureOid` and `signatureParameters`, so the child was verified with the issuer's own scheme rather than the one the child declares.\n\nAs a result, a child certificate whose signature algorithm says RSASSA-PSS was accepted with a PKCS#1 v1.5 signature when the issuer itself was signed with PKCS#1 v1.5. The outer `signatureAlgorithm` field of a certificate is not covered by the signature, so an existing PKCS#1 v1.5 (SHA-256) certificate can be relabeled as RSASSA-PSS and still pass verification. The signature itself must still be made with the issuer's private key over the certificate's contents; no certificate can be forged.\n\nThe same cause made correctly signed chains fail: a PKCS#1 v1.5 certificate issued by an RSASSA-PSS-signed certificate, or the reverse, was rejected.\n\nThe fix verifies with the child certificate's signature scheme and parameters and the issuer's public key.\n\n### Patches\nFixed in node-forge 1.4.1. Certificate signatures are verified with the scheme of the certificate's own signature algorithm.\n\n### Workarounds\nApplications that make decisions based on a certificate's signature algorithm can verify the signature themselves with that algorithm's scheme and the issuer's public key.\n\n### References\n- https://www.rfc-editor.org/rfc/rfc4055#section-3 (RSASSA-PSS signature algorithm in certificates)\n- https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.2 (Certificate signatureAlgorithm)\n- https://cwe.mitre.org/data/definitions/347.html (CWE-347: Improper Verification of Cryptographic Signature)\n\n### Severity\nCVSS 3.1: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N (3.7, Low)\nCVSS 4.0 (informational): CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N (6.3)\nCVSS 4.0 rates this Moderate because its integrity weighting is higher; the severity rating follows CVSS 3.1.\n\n### Credits\nReported by Brian Lee (@hibrian827, Georgia Tech SSLab, Team Atlanta), who also suggested the fix.\n\n### Proof of concept\n\nCreate a CA certificate signed with sha256WithRSAEncryption, and a leaf certificate whose signature algorithm fields (outer and in the TBSCertificate) are RSASSA-PSS with SHA-256/MGF1-SHA-256/salt 32, but sign the leaf's TBSCertificate with the CA key using PKCS#1 v1.5 (`caKey.sign(sha256)`).\n\nOn 1.4.0, `forge.pki.verifyCertificateChain(forge.pki.createCaStore([ca]), [leaf])` returns `true`, although verifying the leaf's signature with RSASSA-PSS fails. On 1.4.1 it throws \"Certificate signature is invalid.\".\n\nNo private key is needed for the same result: take any certificate signed by the CA with sha256WithRSAEncryption and replace only its outer signatureAlgorithm (outside the signed TBSCertificate) with the RSASSA-PSS identifier above. On 1.4.0 it still verifies and reports `signatureOid` as RSASSA-PSS; on 1.4.1 it is rejected.\n\nRegression tests are in tests/unit/x509.js (\"signature scheme of the child certificate\").\n\n### Impact\n\nApplications that rely on a certificate's declared signature algorithm, for example a policy that only accepts RSASSA-PSS-signed certificates, can be given a certificate labeled RSASSA-PSS whose signature was verified as PKCS#1 v1.5. The certificate must still have been signed by the trusted issuer's key, so the identity it certifies cannot be forged. There is no confidentiality or availability impact.","status":"published","published":"2026-11-10T15:57:48Z","modified":"2026-11-10T15:57:49Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"}],"cwes":["CWE-347"],"updated_at":"2026-11-10T16:25:10.795148Z"}],"nvd":[{"id":"CVE-2026-118774","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used certificate.verify(child), _verifySignature(), lib/x509.js to process the relevant input or security decision. node-forge selected RSA padding and RSASSA-PSS parameters from the issuer certificate rather than the child certificate being verified. A child labeled as RSASSA-PSS could therefore be accepted with a PKCS#1 v1.5 signature when the issuer used PKCS#1 v1.5. The signature still had to be produced with the trusted issuer's private key, so this did not permit certificate identity forgery, but it could bypass policies that require a declared signature scheme. This issue is fixed in version 1.4.1.","status":"published","published":"2026-10-29T19:17:19.863Z","modified":"2026-11-04T14:57:16.28Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low","assessor":"secondary"},{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"medium","assessor":"primary"}],"cwes":["CWE-347"],"updated_at":"2026-11-04T16:04:29.905777Z"}],"osv":[{"id":"CVE-2026-118774","title":"Forge: Certificate signature verified with the issuer's RSA signature scheme","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used certificate.verify(child), _verifySignature(), lib/x509.js to process the relevant input or security decision. node-forge selected RSA padding and RSASSA-PSS parameters from the issuer certificate rather than the child certificate being verified. A child labeled as RSASSA-PSS could therefore be accepted with a PKCS#1 v1.5 signature when the issuer used PKCS#1 v1.5. The signature still had to be produced with the trusted issuer's private key, so this did not permit certificate identity forgery, but it could bypass policies that require a declared signature scheme. This issue is fixed in version 1.4.1.","status":"published","published":"2026-10-29T18:33:46.399Z","modified":"2026-11-05T21:32:20.579112213Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"}],"cwes":["CWE-347"],"updated_at":"2026-11-05T22:00:34.245765Z"},{"id":"GHSA-9wg5-mj3p-v49q","title":"Forge: Certificate signature verified with the issuer's RSA signature scheme","description":"### Summary\n\nWhen verifying a certificate, node-forge chose the RSA padding scheme (PKCS#1 v1.5 or RSASSA-PSS) and PSS parameters from the issuer certificate's own signature algorithm instead of the certificate being verified. A certificate labeled as signed with RSASSA-PSS could pass `verifyCertificateChain()` with a PKCS#1 v1.5 signature. Fixed in node-forge 1.4.1.\n\n### Details\n\n`certificate.verify(child)` in `lib/x509.js` hashes the child's TBSCertificate with the digest of the child's signature algorithm, then calls `_verifySignature()` with the issuer certificate. `_verifySignature()` selected the padding scheme from that certificate's `signatureOid` and `signatureParameters`, so the child was verified with the issuer's own scheme rather than the one the child declares.\n\nAs a result, a child certificate whose signature algorithm says RSASSA-PSS was accepted with a PKCS#1 v1.5 signature when the issuer itself was signed with PKCS#1 v1.5. The outer `signatureAlgorithm` field of a certificate is not covered by the signature, so an existing PKCS#1 v1.5 (SHA-256) certificate can be relabeled as RSASSA-PSS and still pass verification. The signature itself must still be made with the issuer's private key over the certificate's contents; no certificate can be forged.\n\nThe same cause made correctly signed chains fail: a PKCS#1 v1.5 certificate issued by an RSASSA-PSS-signed certificate, or the reverse, was rejected.\n\nThe fix verifies with the child certificate's signature scheme and parameters and the issuer's public key.\n\n### Patches\nFixed in node-forge 1.4.1. Certificate signatures are verified with the scheme of the certificate's own signature algorithm.\n\n### Workarounds\nApplications that make decisions based on a certificate's signature algorithm can verify the signature themselves with that algorithm's scheme and the issuer's public key.\n\n### References\n- https://www.rfc-editor.org/rfc/rfc4055#section-3 (RSASSA-PSS signature algorithm in certificates)\n- https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.2 (Certificate signatureAlgorithm)\n- https://cwe.mitre.org/data/definitions/347.html (CWE-347: Improper Verification of Cryptographic Signature)\n\n### Severity\nCVSS 3.1: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N (3.7, Low)\nCVSS 4.0 (informational): CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N (6.3)\nCVSS 4.0 rates this Moderate because its integrity weighting is higher; the severity rating follows CVSS 3.1.\n\n### Credits\nReported by Brian Lee (@hibrian827, Georgia Tech SSLab, Team Atlanta), who also suggested the fix.\n\n### Proof of concept\n\nCreate a CA certificate signed with sha256WithRSAEncryption, and a leaf certificate whose signature algorithm fields (outer and in the TBSCertificate) are RSASSA-PSS with SHA-256/MGF1-SHA-256/salt 32, but sign the leaf's TBSCertificate with the CA key using PKCS#1 v1.5 (`caKey.sign(sha256)`).\n\nOn 1.4.0, `forge.pki.verifyCertificateChain(forge.pki.createCaStore([ca]), [leaf])` returns `true`, although verifying the leaf's signature with RSASSA-PSS fails. On 1.4.1 it throws \"Certificate signature is invalid.\".\n\nNo private key is needed for the same result: take any certificate signed by the CA with sha256WithRSAEncryption and replace only its outer signatureAlgorithm (outside the signed TBSCertificate) with the RSASSA-PSS identifier above. On 1.4.0 it still verifies and reports `signatureOid` as RSASSA-PSS; on 1.4.1 it is rejected.\n\nRegression tests are in tests/unit/x509.js (\"signature scheme of the child certificate\").\n\n### Impact\n\nApplications that rely on a certificate's declared signature algorithm, for example a policy that only accepts RSASSA-PSS-signed certificates, can be given a certificate labeled RSASSA-PSS whose signature was verified as PKCS#1 v1.5. The certificate must still have been signed by the trusted issuer's key, so the identity it certifies cannot be forged. There is no confidentiality or availability impact.","status":"published","published":"2026-11-10T15:57:48Z","modified":"2026-11-10T16:15:04.153166136Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"}],"cwes":["CWE-347"],"updated_at":"2026-11-10T16:33:22.61896Z"},{"id":"UBUNTU-CVE-2026-118774","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used certificate.verify(child), _verifySignature(), lib/x509.js to process the relevant input or security decision. node-forge selected RSA padding and RSASSA-PSS parameters from the issuer certificate rather than the child certificate being verified. A child labeled as RSASSA-PSS could therefore be accepted with a PKCS#1 v1.5 signature when the issuer used PKCS#1 v1.5. The signature still had to be produced with the trusted issuer's private key, so this did not permit certificate identity forgery, but it could bypass policies that require a declared signature scheme. This issue is fixed in version 1.4.1.","status":"published","published":"2026-10-29T19:17:00Z","modified":"2026-11-06T01:00:07.729340391Z","cvss":[{"version":"3.1","score":3.7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"low"},{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","level":"medium"}],"updated_at":"2026-11-06T01:33:11.614208Z"},{"id":"AZL-112505","title":"CVE-2026-118774 affecting package python-tensorboard 2.16.2-6","description":"Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, the affected implementation used certificate.verify(child), _verifySignature(), lib/x509.js to process the relevant input or security decision. node-forge selected RSA padding and RSASSA-PSS parameters from the issuer certificate rather than the child certificate being verified. A child labeled as RSASSA-PSS could therefore be accepted with a PKCS#1 v1.5 signature when the issuer used PKCS#1 v1.5. The signature still had to be produced with the trusted issuer's private key, so this did not permit certificate identity forgery, but it could bypass policies that require a declared signature scheme. This issue is fixed in version 1.4.1.","status":"published","published":"2026-10-29T19:17:19Z","modified":"2026-11-03T05:33:06Z","updated_at":"2026-11-05T16:41:19.001909Z"},{"id":"CLSA-2026-1794329081","title":"TuxCare security update for node-forge (2 CVEs)","description":"TuxCare rebuilt node-forge to address 2 CVEs. Fixed in 1.3.3-tuxcare.5.","status":"published","published":"2026-11-10T17:44:41Z","modified":"2026-11-10T19:46:07.423483631Z","updated_at":"2026-11-10T20:12:16.608797Z"},{"id":"CLSA-2026-1794330948","title":"TuxCare security update for node-forge (2 CVEs)","description":"TuxCare rebuilt node-forge to address 2 CVEs. Fixed in 1.3.1-tuxcare.5.","status":"published","published":"2026-11-10T18:15:49Z","modified":"2026-11-10T19:46:03.522108279Z","updated_at":"2026-11-10T20:12:20.089751Z"}]}}
