chore(deps): update dependency node-forge to v1.4.0 [security]#103
Merged
chore(deps): update dependency node-forge to v1.4.0 [security]#103
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
1.3.3→1.4.0GitHub Vulnerability Alerts
CVE-2026-33895
Summary
Ed25519 signature verification accepts forged non-canonical signatures where the scalar S is not reduced modulo the group order (
S >= L). A valid signature and itsS + Lvariant both verify in forge, while Node.jscrypto.verify(OpenSSL-backed) rejects theS + Lvariant, as defined by the specification. This class of signature malleability has been exploited in practice to bypass authentication and authorization logic (see CVE-2026-25793, CVE-2022-35961). Applications relying on signature uniqueness (i.e., dedup by signature bytes, replay tracking, signed-object canonicalization checks) may be bypassed.Impacted Deployments
Tested commit:
8e1d527fe8ec2670499068db783172d4fb9012e5Affected versions: tested on v1.3.3 (latest release) and all versions since Ed25519 was implemented.
Configuration assumptions:
ed25519.verify(...)).Root Cause
In
lib/ed25519.js,crypto_sign_open(...)uses the signature's last 32 bytes (S) directly in scalar multiplication:There is no prior check enforcing
S < L(Ed25519 group order). As a result, equivalent scalar classes can pass verification, including a modified signature whereS := S + L (mod 2^256)when that value remains non-canonical. The PoC demonstrates this by mutating only the S half of a valid 64-byte signature.Reproduction Steps
v24.9.0) and clonedigitalbazaar/forgeat commit8e1d527fe8ec2670499068db783172d4fb9012e5.poc.js) withnode poc.jsin the same level as theforgefolder.crypto.verify).{ "forge": { "original_valid": true, "tweaked_valid": true }, "crypto": { "original_valid": true, "tweaked_valid": false } }Proof of Concept
Overview:
poc.js
Suggested Patch
Add strict canonical scalar validation in Ed25519 verify path before scalar multiplication. (Parse S as little-endian 32-byte integer and reject if
S >= L).Here is a patch we tested on our end to resolve the issue, though please verify it on your end:
Resources
Credit
This vulnerability was discovered as part of a U.C. Berkeley security research project by: Austin Chu, Sohee Kim, and Corban Villa.
CVE-2026-33896
Summary
pki.verifyCertificateChain()does not enforce RFC 5280 basicConstraints requirements when an intermediate certificate lacks both thebasicConstraintsandkeyUsageextensions. This allows any leaf certificate (without these extensions) to act as a CA and sign other certificates, which node-forge will accept as valid.Technical Details
In
lib/x509.js, theverifyCertificateChain()function (around lines 3147-3199) has two conditional checks for CA authorization:keyUsagecheck (which includes a sub-check requiringbasicConstraintsto be present) is gated onkeyUsageExt !== nullbasicConstraints.cAcheck is gated onbcExt !== nullWhen a certificate has neither extension, both checks are skipped entirely. The certificate passes all CA validation and is accepted as a valid intermediate CA.
RFC 5280 Section 6.1.4 step (k) requires:
The absence of
basicConstraintsshould result in rejection, not acceptance.Proof of Concept
Results:
basicConstraints.cA=false: correctly rejectedkeyUsage(nokeyCertSign): correctly rejectedAttack Scenario
An attacker who obtains any valid leaf certificate (e.g., a regular TLS certificate for
attacker.com) that lacksbasicConstraintsandkeyUsageextensions can use it to sign certificates for ANY domain. Any application using node-forge'sverifyCertificateChain()will accept the forged chain.This affects applications using node-forge for:
CVE Precedent
This is the same vulnerability class as:
Not a Duplicate
This is distinct from:
Suggested Fix
Add an explicit check for absent
basicConstraintson non-leaf certificates:Disclosure Timeline
Credits
Discovered and reported by Doruk Tan Ozturk (@peaktwilight) — doruk.ch
CVE-2026-33894
Summary
RSASSA PKCS#1 v1.5 signature verification accepts forged signatures for low public exponent keys (e=3). Attackers can forge signatures by stuffing “garbage” bytes within the ASN structure in order to construct a signature that passes verification, enabling Bleichenbacher style forgery. This issue is similar to CVE-2022-24771, but adds bytes in an addition field within the ASN structure, rather than outside of it.
Additionally, forge does not validate that signatures include a minimum of 8 bytes of padding as defined by the specification, providing attackers additional space to construct Bleichenbacher forgeries.
Impacted Deployments
Tested commit:
8e1d527fe8ec2670499068db783172d4fb9012e5Affected versions: tested on v1.3.3 (latest release) and recent prior versions.
Configuration assumptions:
schemeuses RSASSA-PKCS1-v1_5)._parseAllDigestBytes: true(default setting).Root Cause
In
lib/rsa.js,key.verify(...), forge decrypts the signature block, decodes PKCS#1 v1.5 padding (_decodePkcs1_v1_5), parses ASN.1, and comparescapture.digestto the provided digest.Two issues are present with this logic:
_parseAllDigestBytes) only guarantees all bytes are parsed, not that the parsed structure is the canonical minimal DigestInfo shape expected by RFC 8017 verification semantics. A forged EM with attacker-controlled additional ASN.1 content inside the parsed container can still pass forge verification while OpenSSL rejects it._decodePkcs1_v1_5comments mention that PS < 8 bytes should be rejected, but does not implement this logic.Reproduction Steps
v24.9.0) and clonedigitalbazaar/forgeat commit8e1d527fe8ec2670499068db783172d4fb9012e5.repro_min.js) withnode repro_min.jsin the same level as theforgefolder.4096bits,e=3), creates a normal control signature, then computes a forged candidate using cube-root interval construction._parseAllDigestBytes: true), andcrypto.verifywithRSA_PKCS1_PADDING).control-forge-strict: truecontrol-node: trueforgery (forge library, strict): trueforgery (node/OpenSSL): falseProof of Concept
Overview:
_parseAllDigestBytes: true, also forge default).repro_min.js
Suggested Patch
PS >= 8) in_decodePkcs1_v1_5before accepting the block.Here is a Forge-tested patch to resolve the issue, though it should be verified for consumer projects:
Resources
lib/rsa.jskey.verify(...)at lines ~1139-1223.lib/rsa.js_decodePkcs1_v1_5(...)at lines ~1632-1695.Credit
This vulnerability was discovered as part of a U.C. Berkeley security research project by: Austin Chu, Sohee Kim, and Corban Villa.
Release Notes
digitalbazaar/forge (node-forge)
v1.4.0Compare Source
Security
BigInteger.modInverse()the
BigInteger.modInverse()function (inherited from the bundled jsbnlibrary). When
modInverse()is called with a zero value as input, theinternal Extended Euclidean Algorithm enters an unreachable exit condition,
causing the process to hang indefinitely and consume 100% CPU.
public exponent keys (e=3). Attackers can forge signatures by stuffing
"garbage" bytes within the ASN.1 structure in order to construct a
signature that passes verification, enabling Bleichenbacher style forgery.
This issue is similar to CVE-2022-24771, but adds bytes in an addition
field within the ASN.1 structure, rather than outside of it.
8 bytes of padding as defined by the specification, providing attackers
additional space to construct Bleichenbacher forgeries.
Ed25519due to missing S < L check.Ed25519signature verification accepts forged non-canonical signatureswhere the scalar S is not reduced modulo the group order (S >= L). A valid
signature and its S + L variant both verify in forge, while Node.js
crypto.verify (OpenSSL-backed) rejects the S + L variant, as defined by the
specification. This class of signature malleability has been exploited in
practice to bypass authentication and authorization logic (see
CVE-2026-25793, CVE-2022-35961). Applications relying on signature
uniqueness (i.e., dedup by signature bytes, replay tracking, signed-object
canonicalization checks) may be bypassed.
basicConstraintsbypass in certificate chain verification.pki.verifyCertificateChain()does not enforce RFC 5280basicConstraintsrequirements when an intermediate certificate lacks both the
basicConstraintsandkeyUsageextensions. This allows any leafcertificate (without these extensions) to act as a CA and sign other
certificates, which node-forge will accept as valid.
Added
2.5.4.65/pseudonymChanged
jsbn1.4. Sync partly back to original style for easierupdates every decade or so.
Fixed
BigInteger.modInverseto avoid an infinite loop and exit earlywith zero when the target object value is <= 0. Zero may not be strictly
mathematically correct but aligns with current
jsbnbehavior returning zeroin other situations. The alternate of a
RangeErrorwould diverge from therest of the API.
required to be eight octets for block types 1 and 2.
ed25519] Add canonical signature scaler check for S < L.basicConstraintson non-leafcertificates.
Configuration
📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.