CVE-2026-73086 Overview
CVE-2026-73086 is an integer overflow vulnerability [CWE-190] in nanoid, a widely used URL-friendly unique string ID generator for JavaScript. The nanoid(size) function in index.js and index.cjs coerces the user-influenced size parameter to a signed 32-bit integer. Supplying the value 2147483648 wraps to -2147483648 and corrupts the process-wide CSPRNG poolOffset inside fillPool(). After corruption, subsequent generated IDs collapse to the deterministic string "uuuuuuuuuuuuuuuuuuuuu" until the process restarts. Affected identifiers include session tokens, CSRF tokens, API keys, and unique record IDs. The issue is fixed in versions 3.3.12 and 5.1.11.
Critical Impact
Once triggered, all downstream nanoid outputs become predictable across the entire Node.js process, undermining authentication and session integrity.
Affected Products
- nanoid versions prior to 3.3.12
- nanoid versions prior to 5.1.11
- Node.js applications passing untrusted input to nanoid(size)
Discovery Timeline
- 2026-08-11 - CVE-2026-73086 published to NVD
- 2026-08-12 - Last updated in NVD database
Technical Details for CVE-2026-73086
Vulnerability Analysis
The vulnerability originates in the fillPool(bytes) routine used by nanoid to lazily allocate a shared random-byte pool. The function only guarded against negative sizes with if (bytes < 0) bytes = 0, but it did not cap the upper bound. When callers pass 2147483648, JavaScript numeric operations that coerce to a signed 32-bit integer wrap the value to -2147483648. The corrupted poolOffset state then persists at module scope, poisoning every subsequent call to nanoid() in the same process.
Because nanoid is often used to mint session tokens, CSRF tokens, and API keys, the deterministic post-corruption output ("uuuuuuuuuuuuuuuuuuuuu") enables trivial token forgery, session collisions, and authentication bypass across the affected process.
Root Cause
The root cause is missing upper-bound validation on the size argument combined with implicit signed 32-bit coercion during buffer arithmetic. The pool state is stored in module-scope variables (pool, poolOffset), so a single malformed request permanently degrades randomness for the process lifetime.
Attack Vector
Exploitation requires an attacker to influence the size argument passed to nanoid(size). Applications that expose ID length via query parameters, JSON bodies, or configuration values fed from untrusted input are reachable over the network. Successful exploitation is a persistent, process-wide denial-of-randomness that converts into an integrity attack against issued credentials.
// Security patch in index.js - Limit ID even more
let pool, poolOffset
function fillPool(bytes) {
- if (bytes < 0) bytes = 0
+ if (bytes < 0 || bytes > 1024) throw new RangeError('Wrong ID size')
if (!pool || pool.length < bytes) {
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
crypto.getRandomValues(pool)
// Source: https://github.com/ai/nanoid/commit/7087969281cab8ba8ae3babf1894e819068b3bb4
The patch replaces silent clamping with an explicit RangeError when bytes is negative or exceeds 1024, preventing the overflow condition entirely. A parallel backport commit applies the same guard in the 3.x line, and a CommonJS fix covers index.cjs.
Detection Methods for CVE-2026-73086
Indicators of Compromise
- Generated IDs containing the deterministic string uuuuuuuuuuuuuuuuuuuuu in logs, databases, or issued tokens.
- Repeated session or CSRF tokens across otherwise unrelated user sessions.
- HTTP request bodies or query parameters containing the value 2147483648 targeting ID-generation endpoints.
- Application logs showing RangeError: Wrong ID size after patching, indicating attempted exploitation.
Detection Strategies
- Perform a dependency audit with npm ls nanoid and flag any version below 3.3.12 on the 3.x line or 5.1.11 on the 5.x line.
- Query application datastores for token or ID columns matching the regex ^u{10,}$ to identify prior corruption.
- Add web application firewall rules that reject requests where numeric ID-length parameters exceed a small application-defined maximum.
Monitoring Recommendations
- Monitor server-side error telemetry for RangeError exceptions originating in nanoid after upgrade.
- Alert on collisions of unique-by-design fields (session ID, CSRF token, API key) written to durable storage.
- Track process uptime for services generating IDs; unusual restarts may indicate mitigation attempts after corruption.
How to Mitigate CVE-2026-73086
Immediate Actions Required
- Upgrade nanoid to 3.3.12 or 5.1.11 across all Node.js services and rebuild container images.
- Invalidate all active session tokens, CSRF tokens, and API keys that may have been minted by a compromised process.
- Audit application code for paths where the size argument to nanoid() is derived from user input and add strict validation.
Patch Information
The fix is available in nanoid 3.3.12 and nanoid 5.1.11. Full technical details are published in the GitHub Security Advisory GHSA-xwg4-73v4-xw9w.
Workarounds
- If immediate upgrade is not possible, wrap all nanoid() calls in a helper that validates size is a positive integer no greater than 1024 before invocation.
- Remove any application feature that lets external callers control the ID length; hardcode the size to a safe constant.
- Restart affected Node.js processes on a schedule to bound the window of pool corruption until the patched version is deployed.
# Configuration example: upgrade and verify
npm install nanoid@^3.3.12 # for 3.x consumers
npm install nanoid@^5.1.11 # for 5.x consumers
npm ls nanoid # confirm no vulnerable versions remain in the tree
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

