Zion Boggan

In-depth vulnerability research, detection engineering & applied cryptography.

● Open to security-research & detection roles
GitHub · LinkedIn · Email
← Research notebook
Info disclosure

Email Enumeration Timing

SUBMISSION 2

TITLE: User Email Enumeration via /v1/userauth Error Message and Timing Difference

TARGET: api.aiven.io (https://api.aiven.io/login)

VRT CATEGORY: Broken Authentication and Session Management > Username/Email Enumeration > Non-Brute Force

URL: https://api.aiven.io/v1/userauth

DESCRIPTION:

Summary

The login endpoint POST /v1/userauth returns different error messages and response times for registered vs unregistered email addresses, enabling unauthenticated user enumeration.

  • Non-existent email: "User does not exist", ~150ms response
  • Existing email: "user_password_compromised", ~2,500-5,200ms response

The dual oracle (message + timing) makes enumeration highly reliable. Notably, the password reset endpoint (/v1/user/password_reset_request) is properly implemented and returns a uniform response regardless of email existence.

Steps to Reproduce

  1. Send a request with a non-existent email:
curl -s -w "\nTime: %{time_total}s" -X POST https://api.aiven.io/v1/userauth \
 -H "Content-Type: application/json" \
 -d '{"email":"[email protected]","password":"test123"}'

Response: HTTP 403, ~150-477ms

{"errors":[{"message":"User does not exist","status":403}]}
  1. Send a request with a known existing email:
curl -s -w "\nTime: %{time_total}s" -X POST https://api.aiven.io/v1/userauth \
 -H "Content-Type: application/json" \
 -d '{"email":"[email protected]","password":"wrongpassword123!"}'

Response: HTTP 403, ~5,225ms

{"errors":[{"error_code":"user_password_compromised","message":"Your login is blocked because your password is no longer safe. Reset your password to log in.","status":403}]}
  1. Additional tests confirming the pattern:
Email Message Time Exists?
[email protected] “User does not exist” ~150ms No
[email protected] “user_password_compromised” ~5,225ms Yes
[email protected] “user_password_compromised” ~2,688ms Yes
[email protected] “User does not exist” ~150ms No

Impact

An attacker can determine which email addresses are registered on Aiven. This enables targeted credential stuffing against confirmed accounts and targeted phishing campaigns impersonating Aiven (e.g., fake password reset emails). The 10-35x timing difference makes automated enumeration reliable even if error messages were normalized.

Root Cause

The API checks email existence before password validation and returns distinct error messages. The timing difference is likely caused by an additional breach database (HIBP) lookup that only occurs for existing accounts.

Suggested Fix

Return a generic "Invalid credentials" message for all authentication failures and normalize response timing.


Source · github.com/zionsworking/security-research-notebook · writeups/aiven/email-enumeration-timing.md