fix(auth): run dummy Argon2 verify for non-existent users to prevent timing enumeration

用户不存在时执行一次固定合法哈希的 verify(必然失败),抹平与「密码错误」
路径的时序差,防止通过响应时间枚举账号(L2)。dummy 哈希走 spawn_blocking,
与真实校验路径耗时一致;响应消息保持一致。
This commit is contained in:
xfy 2026-06-18 13:29:55 +08:00
parent 05c01ccebe
commit 1c6974ca68

View File

@ -201,6 +201,16 @@ pub async fn login(username: String, password: String) -> Result<AuthResponse, S
{ {
Ok(Some(row)) => row, Ok(Some(row)) => row,
Ok(None) => { Ok(None) => {
// 用户不存在时也执行一次 Argon2 verify抹平「用户不存在」与
// 「密码错误」的响应时序差防止通过响应时间枚举账号L2
// 用固定合法哈希做 verify必然失败耗时与真实校验一致。
const DUMMY_HASH: &str =
"$argon2id$v=19$m=19456,t=2,p=1$j3rNaAXzdExYaL94WBWtfg$n1S75LUQKaYJwaRl5bkFF/f/N1tLfRYR/7TuQxKP94c";
let dummy_pw = password.clone();
let _ = tokio::task::spawn_blocking(move || {
crate::auth::password::verify_password(&dummy_pw, DUMMY_HASH)
})
.await;
return Ok(AuthResponse { return Ok(AuthResponse {
success: false, success: false,
message: "Invalid credentials".to_string(), message: "Invalid credentials".to_string(),