Tag: low

  • GHSA-4642-5mcj-2rqw: Forge: ASN.1 OID first arc truncation in asn1.oidToDer

    • Severity: LOW
    • CVE: CVE-2026-118775
    • Ecosystems: npm
    • Packages: node-forge

    ### Summary

    `asn1.oidToDer()` did not range-check the first two arcs of an OID string, so an OID such as `0.42.840.113549.1.1.1` or `4294977127.18.840.113549.1.1.1` was encoded as the DER of a different OID (here rsaEncryption, `1.2.840.113549.1.1.1`). This is an incomplete fix of CVE-2025-66030. Fixed in node-forge 1.4.1.

    ### Details

    X.690 section 8.19 encodes the first two arcs of an OID as one subidentifier, `40 * arc1 + arc2`, where the first arc is 0, 1 or 2 and the second arc is at most 39 when the first is 0 or 1. `asn1.oidToDer()` in `lib/asn1.js` computed that value with no range check and wrote it with `putByte()`, which keeps only the low 16 bits. Out-of-range first arcs therefore produced the encoding of a different OID: `0.42.840.113549.1.1.1` gives `40 * 0 + 42 = 42` and `4294977127.18.840.113549.1.1.1` wraps to 42, both the first byte of rsaEncryption. The fix for CVE-2025-66030 (GHSA-65ch-62r8-g69g, node-forge 1.3.2) added a 32-bit check for the later arcs only.

    A related encoding bug made valid OIDs with a first subidentifier above 127 (`2.48` and higher, e.g. `2.999`) encode and decode incorrectly, because the first subidentifier was always written and read as a single byte.

    The fix rejects out-of-range first arcs and encodes and decodes the first subidentifier in base 128 like the others (the latter from public PR #1148).

    ### Patches
    Fixed in node-forge 1.4.1. `asn1.oidToDer()` throws for OIDs with out-of-range first arcs, and the first subidentifier…

    Source: GitHub Security Advisories · 2026-10-30

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

    • Severity: LOW
    • CVE: CVE-2026-118781
    • Ecosystems: npm
    • Packages: node-forge

    ### 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 “

    Source: GitHub Security Advisories · 2026-10-30

  • GHSA-4487-j8r4-4g2f: Forge: verifyCertificateChain() removes trusted CA certificates with the same subject from the CA store

    • Severity: LOW
    • CVE: CVE-2026-118780
    • Ecosystems: npm
    • Packages: node-forge

    ### Summary

    When a CA store created by `pki.createCaStore()` holds two or more certificates with the same subject name, `pki.verifyCertificateChain()` permanently removes those certificates from the store while trying each one as the issuer. A peer can send any certificate that names that subject as its issuer to make all later verifications against those CA certificates fail. Fixed in node-forge 1.4.1.

    ### Details

    `pki.verifyCertificateChain()` (`lib/x509.js`) asks the CA store for the issuer of each certificate with `caStore.getIssuer()`. When the store holds several certificates with the same subject, `caStore.getIssuer()` returns the store’s own internal array of those certificates (`caStore.certs[hash]`, built by `addCertificate()`). `verifyCertificateChain()` used that array directly as its list of candidate parents and called `parents.shift()` on it while trying each candidate. Every candidate it tried, including the one that finally verified the certificate, was removed from the store.

    Once the array is empty, `getIssuer()` returns an empty list, no candidate is tried, and verification fails with “Certificate signature is invalid.” `hasCertificate()` and `listAllCertificates()` no longer see the removed certificates. The store stays in this state for as long as the object is used.

    The attacker’s certificate only needs an issuer name equal to the shared subject name, which is public. Its signature and key can be arbitrary: every candidate is tried and shifted out…

    Source: GitHub Security Advisories · 2026-10-30