GitHub Advisoryadvisory · npm
GHSA-jc66-7q78-782g Forge: PKCS#12 MAC forgery and constant-key PBE via zero iteration count
HIGH
Official page ↗
- Aliases
- CVE-2026-118782
- Ecosystem
- npm
- Packages
- node-forge
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
- Weaknesses
- CWE-1284, CWE-354
- Reviewed
- 2026-10-30
Affected packages
• npm node-forge: < 1.4.1 → fixed in 1.4.1
Description
Summary
forge.pkcs12.pkcs12FromAsn1() accepts a PKCS#12 MAC iteration count of zero (or less) from the input, and the PKCS#12 key derivation function then returns a constant key that does not depend on the password or salt. An attacker who does not know the password can modify a PKCS#12/PFX file and compute a MAC that verifies with any password; PKCS#12 PBE-encrypted private keys prepared the same way decrypt with any password. Fixed in node-forge 1.4.1.
Details
`p12.pkcs12FromAsn1()` in `lib/pkcs12.js` reads the MAC iteration count (`MacData.iterations`) from the input and passes it to the PKCS#12 key derivation function `pki.pbe.generatePkcs12Key()` in `lib/pbe.js` (also exposed as `forge.pkcs12.generateKey()`) without checking that it is at least 1. The key derivation function (RFC 7292 Appendix B.2) runs its hash loop `iter` times. With an iteration count of 0 (or an empty or negative INTEGER), no hashing is done and the function returns the PKCS#12 diversifier ID byte repeated, for example `0x03` repeated 20 times for an HMAC-SHA1 MAC key. The result does not depend on the password or the salt, so anyone can compute a valid MAC over arbitrary PFX contents.
The same key derivation function is used by `pki.pbe.getCipherForPKCS12PBE()` for the PKCS#12 password-based encryption schemes `pbeWithSHAAnd3-KeyTripleDES-CBC` and `pbewithSHAAnd40BitRC2-CBC`, whose `pkcs-12PbeParams` iteration count is also read from the input. With an iteration count of 0 or less, the encryption key and IV are constants (`0x01` and `0x02` repeated). This is reached from shrouded key bags and encrypted SafeContents in `pkcs12FromAsn1()`, and from `forge.pki.decryptPrivateKeyInfo()` (for example for `ENCRYPTED PRIVATE KEY` PEM input).
RFC 7292 defines `MacData` with `iterations INTEGER DEFAULT 1`; an iteration count only makes sense as 1 or more (RFC 8018 uses `INTEGER (1..MAX)` for the same concept). PBES2 (PBKDF2) encrypted content is not affected.
The fix rejects iteration counts less than 1 when verifying a PKCS#12 MAC in `pkcs12FromAsn1()` ("PKCS#12 MAC iteration count must be >= 1.") and at the entry of `pki.pbe.generatePkcs12Key()` ("PKCS#12 key derivation iteration count must be >= 1."), which covers the MAC, both PKCS#12 PBE schemes and direct `forge.pkcs12.generateKey()` callers.
Patches
Fixed in node-forge 1.4.1. Iteration counts less than 1 are now rejected when verifying a PKCS#12 MAC and in the PKCS#12 key derivation function.
Workarounds
Before calling `forge.pkcs12.pkcs12FromAsn1()`, reject inputs whose `MacData.iterations` is present and less than 1. For encrypted private keys using the PKCS#12 PBE schemes, there is no simple workaround other than checking the `pkcs-12PbeParams` iteration count before decryption, or upgrading.
Credits
Reported by Thai, Calif.io in collaboration with Claude and Anthropic Research.
Proof of concept
Take any PKCS#12/PFX file, replace its AuthenticatedSafe with attacker-chosen content (for example the attacker's certificate and an unencrypted private key), set `MacData.iterations` to 0 (DER `02 01 00`), and compute the HMAC-SHA1 over the new content with the key `0x03` repeated 20 times. On node-forge = 1."
```
The fix adds regression tests in `tests/unit/pkcs12.js` and the reporter's PoC in `tests/pocs/`.
Impact
Applications that import PKCS#12/PFX files or PKCS#8 encrypted private keys from untrusted sources with `forge.pkcs12.pkcs12FromAsn1()` or `forge.pki.decryptPrivateKeyInfo()`, and rely on the password-based MAC or on successful decryption to establish that the file was produced by someone who knows the password. The default API and call pattern are affected; no password, oracle or user interaction is needed, only one offline HMAC.
An attacker can supply a PKCS#12 file with certificates and private keys of their choice (for example, replaced certificates or an unencrypted private key) that node-forge reports as verified under the application's password. The attacker does not learn the password or the original private key. PBES2 (PBKDF2) encrypted content is not affected.
Related
Alias · CVE (1)
- CVE-2026-118782 Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. vulnerability
References
- https://github.com/digitalbazaar/forge/security/advisories/GHSA-jc66-7q78-782g web
- https://nvd.nist.gov/vuln/detail/CVE-2026-118782 advisory
- https://github.com/digitalbazaar/forge/commit/d9584aa56824972858366d5187b3d29e46bf3656 web
- https://github.com/digitalbazaar/forge package
- https://github.com/digitalbazaar/forge/releases/tag/v1.4.1 web