Executive brief
nanoid is a widely-used JavaScript library for generating unique random identifiers. A flaw in how it handles oversized size parameters causes the internal randomness pool to become permanently corrupted, making all subsequently generated IDs predictable and identical. An attacker can trigger this with a single malicious request to any application that passes user input to the size parameter, leading to session hijacking and account takeover.
Technical details
The vulnerability is an integer overflow in the size parameter handling at index.js:101. The code coerces size with the bitwise OR operator (size |= 0) to convert it to a signed 32-bit integer. When size >= 2^31 (e.g., 2147483648), this wraps to -2147483648. The negative value is passed to fillPool(), which fails to detect the overflow condition because both bounds checks compare against the negative value. poolOffset becomes deeply negative (~-2.1 billion), causing subsequent ID generation loops to read from undefined array indices. Since undefined & 63 evaluates to 0, every ID becomes the character at alphabet[0] repeated, producing "uuuuuuuuuuuuuuuuuuuuu". The corruption persists across all nanoid() calls in the process until approximately 100 million calls wrap poolOffset back to positive, or the process restarts. No authentication or special privileges are required; a single unauthenticated API request with a crafted size parameter is sufficient to trigger the attack.
Affected products
- ai nanoid < 3.3.12
- ai nanoid >= 4.0.0, < 5.1.11
Timeline
- 2026-08-03: disclosed: Published by ai/nanoid and GitHub Advisory Database
- 2026-08-03: patched: Patches released: version 3.3.12 and version 5.1.11
- 2026-09-01: advisory: CVE-2026-73086 published to National Vulnerability Database