Understanding the Bcrypt Caching Vulnerability
On October 30, 2024, a critical security vulnerability was discovered in Okta’s AD/LDAP Delegated Authentication (DelAuth) affecting usernames with 52 or more characters. The issue, found in product versions released as of July 23, 2024, allowed users to potentially access accounts without entering a password due to a caching flaw in bcrypt.
How This Works
The vulnerability arises when bcrypt is used to hash usernames. Bcrypt’s caching mechanism may mistakenly validate a different username if it closely resembles a legitimate one, especially with longer strings. This flaw could let attackers gain unauthorized access by crafting usernames similar to valid ones
Code Example
Here’s a code example illustrating the issue:
const bcrypt = require("bcryptjs");
const length = 72
// Define long strings for testing
const generateLongString = (length, suffix) => Array(length).fill("A").join("") + suffix;
const string1 = generateLongString(length, "12345");
const string2 = generateLongString(length, "67890");
console.log(`Username length: ${length}`);
console.log({ string1, string2 });
// Hash the strings
const hash1 = bcrypt.hashSync(string1, 10);
const hash2 = bcrypt.hashSync(string2, 10);
// Test comparison
console.log('String1 with Hash1:', bcrypt.compareSync(string1, hash1)); // Expected true
console.log('String1 with Hash2:', bcrypt.compareSync(string1, hash2)); // Potentially true, unexpected
console.log('String2 with Hash1:', bcrypt.compareSync(string2, hash1)); // Potentially true, unexpected
console.log('String2 with Hash2:', bcrypt.compareSync(string2, hash2)); // Expected true

Impact
The issue allowed users with usernames of 52 characters or more to access accounts without entering a password.
Prevention Tips
- Only use bcrypt for password hashing, not usernames.
- Implement strict username validation to prevent similar entries.
- Avoid caching bcrypt results for non-password data.
Read more: Okta Security Advisory