
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-97058 is a Denial of Service vulnerability in the sprintf-js JavaScript library (versions through 1.1.3) caused by improper validation of precision specifiers in format strings. The library passes unbounded precision values directly to ECMAScript's toFixed(), toExponential(), and toPrecision() methods without range checking, causing uncaught RangeError exceptions that can crash the calling Node.js process. The vulnerability was publicly disclosed on September 16, 2026 via a GitHub issue, with CVE assignment and NVD publication on September 24, 2026. It carries a CVSS v3.1 score of 5.3 (Medium) and a CVSS v4.0 score of 6.9 (Medium) (GitHub Issue, Red Hat Advisory, Red Hat Bugzilla).
The root cause is classified as CWE-1284 (Improper Validation of Specified Quantity in Input) and CWE-248 (Uncaught Exception). In src/sprintf.js at line 17, the placeholder regex captures the precision field with an unbounded group (\d+) and stores the raw string value without any numeric range validation. At lines 84, 87, and 90, this unvalidated precision is passed directly to parseFloat(arg).toExponential(ph.precision), parseFloat(arg).toFixed(ph.precision), and Number(arg).toPrecision(ph.precision) respectively — none of which are wrapped in a try/catch block. ECMAScript mandates that toFixed and toExponential accept only 0–100, and toPrecision accepts only 1–100; any value outside these ranges throws a RangeError. Additionally, the %g branch tests truthiness of the string ph.precision, meaning "0" is truthy and forces toPrecision(0), which always throws. A minimal ~6-byte payload such as %.101f deterministically triggers the exception (GitHub Issue, sprintf.js source).
The primary impact is availability loss (Denial of Service) with no confidentiality or integrity impact. When sprintf() is invoked from an asynchronous handler — the common pattern for i18n template rendering — the uncaught RangeError propagates to the Node.js event loop, and Node's default policy terminates the entire worker process with exit code 1, dropping all concurrent and subsequent requests. In synchronous call sites where the caller wraps sprintf() in a try/catch, the impact is limited to a failed individual request (HTTP 500). The attack requires negligible CPU and memory resources, bypassing size-, memory-, and duration-based defenses, and a single malicious request can take down an entire worker (GitHub Issue).
A public proof-of-concept (PoC) is available in the GitHub issue that originally disclosed the vulnerability, demonstrating process termination with a standalone JavaScript script requiring no external infrastructure (GitHub Issue). The vulnerability is network-exploitable, requires no authentication, no user interaction, and no special preconditions beyond the attacker controlling or influencing the format string argument passed to sprintf(). The EPSS score is 0.00366 (~0.37%), indicating low but non-negligible probability of exploitation in the wild. No active in-the-wild exploitation has been observed, and the vulnerability is not listed in the CISA KEV catalog. No threat actor attribution is available (Red Hat Advisory).
sprintf-js version ≤ 1.1.3 and exposes an endpoint where attacker-controlled input influences a format string passed to sprintf() — common in i18n/template rendering, logging, or API response formatting.%.101f, %.101e, %.101g, or %.0g. These are minimal (~6-byte) payloads that deterministically trigger the vulnerability.sprintf() call.sprintf_parse function captures the precision 101 without validation; sprintf_format then calls parseFloat(arg).toFixed(101) (or equivalent), which throws RangeError: toFixed() digits argument must be between 0 and 100.uncaughtException handler is installed, the RangeError propagates to the Node.js event loop, terminating the entire worker process with exit code 1 and dropping all concurrent requests (GitHub Issue).RangeError: toFixed() digits argument must be between 0 and 100 (or toExponential/toPrecision variants) with a stack trace originating in sprintf-js/src/sprintf.js at lines 84, 87, or 90.%.101f, %.101e, %.0g).%.101f, %.NNNf where NNN > 100, or %.0g) in query parameters, POST body fields, or headers that are passed to template/i18n rendering functions.Upgrade sprintf-js to a version newer than 1.1.3 once a patched release is available; a patch has been identified (GitHub Advisory, Red Hat Bugzilla). As an immediate workaround for consumers, never pass attacker-influenced strings as the format argument to sprintf(); wrap all sprintf() calls on untrusted format strings in a try/catch block to prevent uncaught exceptions from reaching the event loop. Additionally, implement input validation to restrict format string precision specifiers to values within valid ECMAScript limits (0–100 for toFixed/toExponential, 1–100 for toPrecision) before passing them to the library. Installing a global uncaughtException handler in Node.js can prevent full process termination but does not fix the underlying vulnerability (GitHub Issue).
Fix availability across major Linux distributions and their releases.
bionic (esm-apps)
node-sprintf-js
devel
node-sprintf-js
focal (esm-apps)
node-sprintf-js
jammy
node-sprintf-js
jammy (esm-apps)
node-sprintf-js
noble
node-sprintf-js
noble (esm-apps)
node-sprintf-js
resolute
node-sprintf-js
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."