When generating unique IDs in JavaScript, nanoid (Nano ID) is one of the most popular libraries around. It's fast, tiny, and widely trusted in the Node.js and frontend world. But recently, a vulnerability—CVE-2024-55565—was discovered that puts some projects at real risk. Let’s break it down in plain English, with code snippets and everything you need to know.

What Is CVE-2024-55565?

CVE-2024-55565 is a vulnerability caused by mishandling non-integer values in the nanoid package, affecting versions before 5..9 (and 3.x before 3.3.8). In plain terms: if you accidentally give nanoid something that isn’t a whole number, it can create IDs that don’t work as expected. This can lead to broken uniqueness, possible collisions, or even weird errors in applications depending on nanoid for secure or unique ID strings.

How Does the Bug Work?

The problem arises because old versions of nanoid do not properly validate the type of the length parameter. The ID generator expects an integer, but nothing stops you from passing a floating point number, a string, etc.

Vulnerable nanoid Code Example

// Affected versions - before 5..9
const { nanoid } = require('nanoid');

// What happens if you pass a float length?
console.log(nanoid(10.5)); // 👈 Uh oh!
// Or a string:
console.log(nanoid('10')); // 👈 Uh oh!

In older nanoid, this doesn't throw an error. Instead, it tries to use the value as-is, which leads to weird behavior:

A string like "10" might become NaN or trigger unexpected length logic.

This could be exploited if an attacker is able to control the length parameter, intentionally giving a non-integer (or something else weird) and causing the app to generate predictable or otherwise broken IDs.

If your app uses user-supplied length for nanoid, an attacker could try

// Attacker passes something weird as length
let userInput = 'foo'; // or maybe 3.14159

let id = nanoid(userInput);

console.log(id); 
// Output might be an empty string, 'undefined', or break your app logic.

If your system expects IDs to always be a certain length and format, and you end up with broken IDs, this could:

Break database constraints (e.g., duplicate primary keys)

- Break validations or input/output systems

Allow collisions if nanoid returns the same result for bad input

Imagine sign-up flows, order tracking, URLs, or session management all possibly producing duplicate or weird IDs due to this bug.

The Fix: Upgrading and Input Validation

nanoID maintainers fixed this in version 5..9 (and 3.3.8). They now check that the length parameter is a positive integer and throw an explicit error otherwise.

Patched Code Example

const { nanoid } = require('nanoid'); // v5..9+

// These now throw errors:
try {
  nanoid(2.7);    // Throws!
  nanoid('10');   // Throws!
} catch (error) {
  console.error('Caught error:', error.message);
}

Now if you pass a float, string, or anything that's not a valid integer, you get a descriptive error instantly.

- Add validation to ensure only positive integers are passed

References & Further Reading

- CVE Details (CVE-2024-55565)
- nanoID 5..9 release notes
- nanoID GitHub repo
- Snyk vulnerability report *(check for updates)*

Conclusion

CVE-2024-55565 teaches us that even the tiniest parameter checks can be critical in libraries as widely used as nanoid. Don’t let a small oversight open the door to bugs or security issues. Update, audit, and validate those parameters, and keep shipping safe code!


If you want more deep dives into JavaScript security, follow for more exclusive posts!

Timeline

Published on: 12/09/2024 02:15:19 UTC
Last modified on: 12/12/2024 19:15:13 UTC