security auth_error ai_generated true

有效和无效用户名的登录响应时间不同,导致用户枚举

Login response time differs for valid vs invalid usernames enabling user enumeration

ID: security/timing-attack-user-enumeration-login

其他格式: JSON · Markdown 中文 · English
85%修复率
82%置信度
1证据数
2023-08-05首次发现

版本兼容性

版本状态引入弃用备注
Node.js 20 active
Python 3.11 active
Java 17 active

根因分析

认证逻辑仅在数据库查询确认用户存在后才进行密码哈希比较,导致现有用户名和不存在用户名的请求之间出现可测量的时间差异。

English

The authentication logic performs a password hash comparison only after a database lookup confirms the user exists, causing a measurable time difference between requests for existing and non-existing usernames.

generic

官方文档

https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html

解决方案

  1. 即使当用户不存在时,也始终执行虚拟密码哈希比较。在Node.js中使用bcrypt:const hash = user ? user.hash : DUMMY_HASH; await bcrypt.compare(password, hash);
  2. 对所有密码检查使用常数时间比较函数,如crypto.timingSafeEqual,并确保无论用户是否存在,都执行相同的代码路径。
  3. 对无效用户名和无效密码都实现通用错误消息,并仅在服务器端记录具体原因。

无效尝试

常见但无效的做法:

  1. 50% 失败

    Adding artificial delays to all responses increases latency for legitimate users and may not fully mask the timing difference if the delay is predictable.

  2. 60% 失败

    Removing the user existence check entirely breaks the authentication flow and may allow login with any password for non-existent users unless handled carefully.

  3. 40% 失败

    Using a simple sleep() function after a failed login is easily bypassed by attackers who can sample multiple requests and average out the delay.