CVE-2026-118782: node-forge: PKCS#12 MAC bypass via zero iteration count

GHSA-jc66-7q78-782gHIGH
Published October 30, 2026
CISO Take

node-forge's PKCS#12 parser accepts an iteration count of zero, which makes the key derivation return a constant value independent of the password. An unauthenticated attacker can therefore forge a PFX file, or an encrypted private key, that the library reports as verified under whatever password the application supplies, with no password knowledge or user interaction. The package has 5,436 downstream dependents and 92 other CVEs, so the blast radius is wide. However, the AI link is indirect, since node-forge is a general crypto library and not an AI component. There is no public exploit, no Nuclei template, no KEV listing and no EPSS score yet, so exploitation is not currently observed. Upgrade to node-forge 1.4.1 or later, and prioritize services that import PFX or ENCRYPTED PRIVATE KEY material from untrusted sources, such as client-certificate onboarding, MCP/agent credential stores and model-serving gateways.

Sources:NVDGitHub AdvisoryATLAS

What is the risk?

High (CVSS 7.5, integrity-only impact). Exploitation is trivial and needs one offline HMAC computation, with no authentication or user interaction. Risk depends on whether the application imports PKCS#12/PFX files or PKCS#8 encrypted keys from untrusted sources and treats a successful MAC or decryption as proof of authenticity. No public exploit or active exploitation is known, and EPSS data is unavailable. The AI/ML relevance is indirect, through Node.js AI tooling that bundles node-forge as a transitive dependency.

How does the attack unfold?

Craft forged PFX
The attacker builds a PKCS#12 file with their own certificate and key, sets MacData.iterations to 0, and computes the HMAC with the constant key.
AML.T0017
Deliver to application
The file is submitted through an upload, import or configuration path that calls pkcs12FromAsn1() or decryptPrivateKeyInfo().
AML.T0049
Integrity check bypass
node-forge reports the MAC as verified, or decrypts the key, under any password the application supplies.
Credential substitution
The application trusts the attacker's certificate and key, enabling impersonation, signing with attacker material, or traffic interception.

What systems are affected?

PackageEcosystemVulnerable RangePatched
Anthropic Pythonnpm<= 1.4.01.4.1
4.0K5.4K dependentsPushed 8d ago93% patched~9d to patchFull package profile →

Do you use Anthropic Python? You're affected.

How severe is it?

CVSS 3.1
7.5 / 10
EPSS
0.1%
chance of exploitation in 30 days
Higher than 2% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Moderate

What is the attack surface?

AVACPRUISCIA
AVNetwork
ACLow
PRNone
UINone
SUnchanged
CNone
IHigh
ANone

What should I do?

1 step
  1. 1) Upgrade node-forge to 1.4.1 or later and check transitive dependencies with npm ls node-forge and lockfile audits. 2) Until patched, reject PKCS#12 inputs whose MacData.iterations is present and below 1 before calling pkcs12FromAsn1(), and check the pkcs-12PbeParams iteration count before decrypting. 3) Do not accept PFX or encrypted key files from untrusted sources, and prefer PBES2 (PBKDF2) encryption. 4) Add SCA alerts for node-forge <= 1.4.0 and review code paths that call forge.pkcs12.pkcs12FromAsn1() or forge.pki.decryptPrivateKeyInfo(). 5) Detection: log and inspect PFX uploads with an iteration count of 0, empty or negative, and verify the fingerprints of imported certificates against expected values.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Art. 15-Accuracy, robustness and cybersecurity
ISO 42001
A.10.3-Suppliers
NIST AI RMF
GOVERN 6.1-Policies and procedures for third-party AI risk
OWASP LLM Top 10
LLM03-Supply Chain

Frequently Asked Questions

What is CVE-2026-118782?

node-forge's PKCS#12 parser accepts an iteration count of zero, which makes the key derivation return a constant value independent of the password. An unauthenticated attacker can therefore forge a PFX file, or an encrypted private key, that the library reports as verified under whatever password the application supplies, with no password knowledge or user interaction. The package has 5,436 downstream dependents and 92 other CVEs, so the blast radius is wide. However, the AI link is indirect, since node-forge is a general crypto library and not an AI component. There is no public exploit, no Nuclei template, no KEV listing and no EPSS score yet, so exploitation is not currently observed. Upgrade to node-forge 1.4.1 or later, and prioritize services that import PFX or ENCRYPTED PRIVATE KEY material from untrusted sources, such as client-certificate onboarding, MCP/agent credential stores and model-serving gateways.

Is CVE-2026-118782 actively exploited?

No confirmed active exploitation of CVE-2026-118782 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-118782?

1) Upgrade node-forge to 1.4.1 or later and check transitive dependencies with npm ls node-forge and lockfile audits. 2) Until patched, reject PKCS#12 inputs whose MacData.iterations is present and below 1 before calling pkcs12FromAsn1(), and check the pkcs-12PbeParams iteration count before decrypting. 3) Do not accept PFX or encrypted key files from untrusted sources, and prefer PBES2 (PBKDF2) encryption. 4) Add SCA alerts for node-forge <= 1.4.0 and review code paths that call forge.pkcs12.pkcs12FromAsn1() or forge.pki.decryptPrivateKeyInfo(). 5) Detection: log and inspect PFX uploads with an iteration count of 0, empty or negative, and verify the fingerprints of imported certificates against expected values.

What systems are affected by CVE-2026-118782?

This vulnerability affects the following AI/ML architecture patterns: Model serving and LLM API gateways, Agent frameworks and MCP tool servers, Node.js AI application backends, mTLS and credential management pipelines.

What is the CVSS score for CVE-2026-118782?

CVE-2026-118782 has a CVSS v3.1 base score of 7.5 (HIGH). The EPSS exploitation probability is 0.13%.

What is the AI security impact?

Affected AI Architectures

Model serving and LLM API gatewaysAgent frameworks and MCP tool serversNode.js AI application backendsmTLS and credential management pipelines

MITRE ATLAS Techniques

AML.T0010.001AI Software
AML.T0049Exploit Public-Facing Application

Compliance Controls Affected

EU AI Act: Art. 15
ISO 42001: A.10.3
NIST AI RMF: GOVERN 6.1
OWASP LLM Top 10: LLM03

What are the technical details?

Original Advisory

### 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.4.0, `forge.pkcs12.pkcs12FromAsn1(asn1, password)` reports successful MAC verification for whatever password the application supplies and returns the attacker's certificate and key. An empty or negative iteration count behaves the same way. Likewise, a shrouded key bag or `ENCRYPTED PRIVATE KEY` using `pbeWithSHAAnd3-KeyTripleDES-CBC` with iteration count 0 decrypts with any password. The constant key is visible directly: ```js var salt = new forge.util.ByteBuffer('anysalt'); forge.pkcs12.generateKey('any password', salt, 3, 0, 20).toHex(); // <= 1.4.0: '0303030303030303030303030303030303030303' // 1.4.1: throws "PKCS#12 key derivation iteration count must be >= 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.

Exploitation Scenario

An AI platform lets tenants upload a PKCS#12 bundle to configure mTLS to a private model endpoint or an MCP tool server, and the Node.js backend validates it with node-forge using the tenant's password. The attacker crafts a PFX with their own certificate and an unencrypted private key, sets the MAC iteration count to 0, and computes the HMAC-SHA1 with the constant key 0x03 repeated 20 times. The backend reports the MAC as verified for the supplied password and loads the attacker's identity. Outbound inference or tool traffic is then signed with attacker-controlled credentials, or the trust anchor is replaced, enabling impersonation or traffic interception.

Weaknesses (CWE)

CWE-1284 — Improper Validation of Specified Quantity in Input: The product receives input that is expected to specify a quantity (such as size or length), but it does not validate or incorrectly validates that the quantity has the required properties.

  • [Implementation] Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylis

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

Timeline

Published
October 30, 2026
Last Modified
October 30, 2026
First Seen
October 31, 2026

Related Vulnerabilities