GitHub Advisoryadvisory · npm

GHSA-h6cr-wjv9-3cpp Forge: Denial of Service via infinite loop in BigInteger.modInverse() with negative input (incomplete fix of CVE-2026-33891)

LOW Published 2026-10-30 Modified 2026-10-30 Official page ↗
Aliases
CVE-2026-118781
Ecosystem
npm
Packages
node-forge
Severity
Low
CVSS vector
CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Weaknesses
CWE-835
Reviewed
2026-10-30

Affected packages

• npm node-forge: < 1.4.1 → fixed in 1.4.1

Description

Summary `BigInteger.prototype.modInverse()` in node-forge's bundled jsbn library enters an infinite loop when the value or the modulus is negative, for example when a negative public exponent is passed to `forge.pki.rsa.generateKeyPair()`. This is an incomplete fix of CVE-2026-33891 (GHSA-5m6q-g25r-mvwx), which handled only a zero value. Fixed in node-forge 1.4.1. Details `bnModInverse()` (`lib/jsbn.js`, exposed as `forge.jsbn.BigInteger.prototype.modInverse`) implements the binary extended Euclidean algorithm (Handbook of Applied Cryptography, Algorithm 14.61), which is defined for positive integers. With a negative operand the loop cannot terminate: `rShiftTo` is an arithmetic shift, so a negative value never moves towards zero, and the loop's exit condition (`u` reaching zero) is never met. The calling thread spins at 100% CPU indefinitely; in Node.js this blocks the event loop. Memory does not grow. node-forge 1.4.0 fixed CVE-2026-33891 (GHSA-5m6q-g25r-mvwx) by returning zero early when `this.signum() == 0`, although its changelog describes the check as "= 3`. • Do not call `BigInteger#modInverse()` with negative operands. Reduce the value modulo a positive modulus first (`x.mod(m).modInverse(m)`). Proof of concept A negative public exponent passed to RSA key generation never returns (also with the callback form and with `createKeyPairGenerationState()` / `stepKeyPairGenerationState()`): var forge = require('node-forge'); forge.pki.rsa.generateKeyPair({bits: 256, e: -1}); // hangs at 100% CPU Calling `modInverse()` directly with a negative value or modulus hangs the same way: var BigInteger = forge.jsbn.BigInteger; new BigInteger('-1').modInverse(new BigInteger('7')); // hangs new BigInteger('3').modInverse(new BigInteger('-7')); // hangs With the fix, these calls return zero. The regression tests are in `tests/unit/jsbn.js`. Impact Applications are affected only if they: • pass an untrusted value as the RSA public exponent `e` to `forge.pki.rsa.generateKeyPair()`, `forge.pki.rsa.createKeyPairGenerationState()` or `forge.pki.rsa.stepKeyPairGenerationState()`, or • call `forge.jsbn.BigInteger#modInverse()` directly with negative values derived from untrusted input. An attacker who can supply such a value makes the call hang indefinitely at 100% CPU, which blocks the Node.js event loop (denial of service). Keys and other data parsed by node-forge (DER, PEM, JWK, PKCS#12, X.509, TLS) cannot trigger this issue, and the documented usage of key generation passes a constant exponent (65537). There is no effect on confidentiality or integrity.

Related

Alias · CVE (1)

  • CVE-2026-118781 Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. vulnerability

Weakness · CWE (1)

  • CWE-835 Loop with Unreachable Exit Condition weakness

References