Skip to main content

node-forge EUVDEUVD-2026-113363

| CVE-2026-119186 MEDIUM
Improper Validation of Integrity Check Value (CWE-354)
2026-10-29 GitHub_M GHSA-5cwg-6vw7-rj6p
5.9
CVSS 3.1 · Vendor: GitHub_M
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Target app deriving GCM tagLength from received tag
  2. Delivery
    Send ciphertext with empty or missing authentication tag
  3. Exploit
    Empty computed tag matches empty supplied tag
  4. Execution
    decipher.finish() returns true unauthenticated
  5. Impact
    Application accepts forged or modified plaintext as authentic

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A08:2025 - Software or Data Integrity Failures
ASVS 5.0
V15 - Secure Coding and Architecture Integrity verification
Exploitation Conditions

Exploitation requires the application to call forge.cipher.createDecipher('AES-GCM') and pass a zero-like tagLength value - specifically 0, null, false, '', or '0' (any value that Number()-converts to 0) - most commonly when tagLength is derived from the length of a received authentication tag (e.g. receivedTag.length * 8 for an empty tag) or left as an unset/zero configuration value. The attacker must also supply an empty or missing tag. Limiting factors that sharply narrow real-world exposure: applications that omit tagLength entirely (using the 128-bit default) or pass any fixed valid NIST tag length (128, 120, 112, 104, 96, 64 or 32 bits) are NOT affected, and the flaw only exists in node-forge <= 1.4.0. The impact is restricted to integrity (message forgery/modification); there is no confidentiality or availability impact.

Impact

This is a genuine but conditional integrity flaw, not a blanket critical issue. The CVSS 3.1 vector (AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N, 5.9 Moderate) is internally consistent with the mechanism: the attack is network-reachable and needs no attacker privileges or user interaction (PR:N/UI:N), but AC:H correctly reflects that success depends on a condition outside the attacker's control - the application must call forge.cipher.createDecipher('AES-GCM') with a zero-like tagLength (0, null, false, '', '0'), typically one derived from the length of a received tag. Impact is integrity-only (C:N/I:H/A:N): an empty computed tag makes decipher.finish() accept any ciphertext as authentic, enabling message forgery and, because GCM is a stream cipher, targeted plaintext modification. No EPSS score, KEV listing, or SSVC automatable/technical-impact values were provided in the input, so probabilistic exploitation signals are absent and cannot be weighed. The vuln.today decision label is 'this_month' (not act_now/emergency), and the vendor rates it Moderate; there is no CISA KEV entry, so this should be treated as a scheduled-remediation item rather than an emergency. One divergence worth noting: the vendor's informational CVSS 4.0 vector scores it 8.2 (High) because 4.0 weights the attack preconditions (AT:P) differently; the authoritative rating follows CVSS 3.1 at 5.9. The real-world risk is concentrated in the subset of deployments that derive tagLength from received data - applications that omit tagLength (128-bit default) or pass a fixed valid length are not affected at all.

Exploit ScenarioDerived

An attacker who can deliver ciphertext to an application that starts an AES-GCM decipher with a tagLength derived from received data - e.g. tagLength: receivedTag.length * 8, which is 0 for an empty tag - submits attacker-chosen bytes with an empty or missing authentication tag; on node-forge <= 1.4.0 decipher.finish() returns true, so the forged data is accepted as authentic, and because GCM is a stream cipher an attacker who knows the plaintext can also flip it to chosen values. The GHSA advisory (GHSA-5cwg-6vw7-rj6p) includes a working proof-of-concept snippet demonstrating this; it is a public PoC reference and not independently verified here as standalone weaponized exploit code. Network vector with no authentication or user interaction, but AC:H because it only works when the application already passes a zero-like tagLength.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.2% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 29, 2026

AES-GCM authentication bypass in node-forge (digitalbazaar) versions up to and including 1.4.0: when an application passes a zero-like tagLength (0, null, false, '', or '0') to forge.cipher.createDecipher('AES-GCM') and the supplied authentication tag is empty or missing, decipher.finish() returns true for arbitrary attacker-chosen ciphertext, so forged or modified messages are accepted as authentic. Exploitation is conditional - it requires the application to derive tagLength from received data (for example receivedTag.length * 8 for an empty tag) or to leave it as an unset/zero configuration value; applications that omit tagLength (128-bit default) or pass a fixed valid NIST tag length are not affected. The flaw is integrity-only (C:N/I:H/A:N, CVSS 3.1 5.9 with AC:H) and a public PoC reference exists in the GHSA advisory showing the tagLength: 0 / empty-tag construction; no confirmed active exploitation (CISA KEV) or working exploit code was identified at time of analysis.

RemediationAI

Vendor-released patch: node-forge 1.4.1 (https://github.com/digitalbazaar/forge/releases/tag/v1.4.1), which validates tagLength in modes.gcm.start(), permits only 128, 120, 112, 104, 96, 64 or 32 bits, defaults null/undefined to 128, and throws 'Invalid tag length.' for 0, false, '', '0', 8, 256 and similar values. Upgrade to 1.4.1 or later, then audit every forge.cipher.createDecipher('AES-GCM') call site for a tagLength derived from received data or from configuration, since such code will now throw rather than silently misbehave; note the advisory's compatibility warning that data previously encrypted with an empty tag can no longer be decrypted. If upgrading is not immediately possible, the vendor workaround is to never derive tagLength from received data - pass a fixed valid tag length or omit it for the 128-bit default - and to check the received tag length before start(), e.g. if(tag.length !== 16) { throw new Error('Invalid tag.'); } before decipher.start({iv: iv, tag: tag}); the trade-off is that this guard must be added at every decryption site and does not cover callers that intentionally pass short NIST tag lengths without the corresponding check. Details are in the advisory at https://github.com/digitalbazaar/forge/security/advisories/GHSA-5cwg-6vw7-rj6p and the fix commit at https://github.com/digitalbazaar/forge/commit/236845d96c71207259f91638d0138bba8e2fd624.

Affected VersionsENISA

forge < 1.4.1

Affected Packages

npm node-forge fix: 1.4.1
euvd forge fix: 1.4.1

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in npm, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

node-forge is a pure-JavaScript implementation of TLS and cryptographic primitives for Node.js and browsers, and its GCM mode lives in lib/cipherModes.js with dispatch logic in lib/cipher.js. The root cause class is CWE-354 (improper validation of integrity check value), with the advisory also classifying it as CWE-1284 (improper validation of a specified quantity). modes.gcm.prototype.start() stored the caller-supplied tagLength without validation, and the documentation even stated the option accepted '0-128'. On finish, afterFinish() truncated the 16-byte authentication tag with truncate(16 % (tagLength / 8)); for a value that Number()-converts to 0 this becomes 16 % 0 = NaN, and truncating by NaN yields an empty tag. On decryption the start-time length check (supplied tag must be tagLength / 8 bytes) trivially passes for an empty tag, so the final comparison compares two empty strings and returns true. NIST SP 800-38D section 5.2.1.2 permits only 128, 120, 112, 104 and 96 bits (plus 64 and 32 for specific applications); the fix in 1.4.1 converts tagLength with Number(), treats null/undefined as the 128-bit default, rejects anything outside that NIST set with 'Invalid tag length.', and still accepts numeric strings such as '128'. Because GCM is a stream cipher, an attacker who knows part of a captured message's plaintext can also rewrite it to chosen values once the tag check is bypassed. The trigger is documented precisely in the GHSA, including PoC code and regression tests in tests/unit/aes.js.

Know when Forge gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (GitHub_M) PRIMARY 5.9 MEDIUM
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N
vuln.today AI 5.9 MEDIUM

Network-delivered forgery needing no attacker privileges or interaction (PR:N/UI:N), but AC:H because success depends on the app using a zero-like tagLength outside attacker control; integrity-only impact.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N
4.0 AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N

Primary rating from Vendor (GitHub_M).

CVSS VectorVendor: GitHub_M

Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
High
Availability
None

Lifecycle Timeline

2
Patch available
Oct 29, 2026 - 20:18 EUVD
CVE Published
Oct 29, 2026 - 19:17 cve.org
MEDIUM 5.9

DescriptionCVE.org

Forge (also called node-forge) is a native implementation of Transport Layer Security in JavaScript. Prior to 1.4.1, node-forge did not validate the AES-GCM tagLength option passed to start() during decryption through forge.cipher.createDecipher(). When an application derived tagLength from received data or used an unset or zero-like configuration value, a value that converted to zero together with an empty or missing authentication tag caused the calculated and supplied tags to compare as empty, so decipher.finish() accepted unauthenticated ciphertext. Applications that omit tagLength to use the 128-bit default or pass a fixed valid tag length are unaffected. This issue is fixed in version 1.4.1.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 6 npm packages depend on node-forge (3 direct, 3 indirect)

Ecosystem-wide dependent count for version 1.4.1.

Threat Intelligence Overview

EPSS Score
0.2%
Top 89% exploitable
Prevalence
High
node-forge is an extremely popular npm crypto/TLS library, tens of millions of weekly downloads
Threat Intel
1
1 source
Data Quality
6 sources
Confidence: High
EUVD NVD CVE.org EPSS Vulnrichment GHSA GitHub

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC No
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
No
Human Impact· derived
High
Technical Impact
Partial

Priority Score

30
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +30
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

More in Forge

View all
CVE-2025-12816 HIGH POC
8.6 Nov 25

An interpretation-conflict (CWE-436) vulnerability in node-forge versions 1.3.1 and earlier enables unauthenticated atta

CVE-2020-7720 HIGH POC
7.3 Sep 01

The package node-forge before 0.10.0 is vulnerable to Prototype Pollution via the util.setPath function. Rated high seve

CVE-2026-85393 HIGH
8.7 Sep 03

RSA PKCS#1 v1.5 signature forgery in node-forge through v1.4.0 enables unauthenticated network attackers to craft signat

CVE-2025-66031 HIGH
8.7 Nov 26

Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Rated high severi

CVE-2026-118779 HIGH
7.5 Oct 29

Regular expression denial of service in node-forge's pem.decode() allows remote, unauthenticated attackers to block the

CVE-2026-119191 HIGH
7.5 Oct 29

Denial of service in node-forge (Forge) 1.3.2 through 1.4.0 lets remote, unauthenticated attackers exhaust CPU time and

CVE-2026-119188 HIGH
7.5 Oct 29

Denial of service in node-forge's JavaScript TLS implementation: a connection created with forge.tls.createConnection()

CVE-2026-119187 HIGH
7.5 Oct 29

Call stack exhaustion in node-forge's TLS record processing (all versions through 1.4.0) allows a remote peer to crash o

CVE-2026-118782 HIGH
7.5 Oct 29

PKCS#12 MAC forgery and constant-key password-based decryption in node-forge 1.4.0 and earlier let anyone who does not k

CVE-2022-24772 HIGH
7.5 Mar 18

Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Rated high severi

CVE-2022-24771 HIGH
7.5 Mar 18

Forge (also called `node-forge`) is a native implementation of Transport Layer Security in JavaScript. Rated high severi

CVE-2026-119190 HIGH
7.4 Oct 29

Certificate chain validation in node-forge (Forge) through version 1.4.0 can be bypassed because the parser maps the dep

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy