多數面向使用者的驗證機制都用「使用者名稱」來控制資源存取,通常再搭配密碼之類的權杖來完成驗證。使用者身分本身不必是祕密——使用者名稱經常就是公開可得的電子郵件位址。
即便如此,不讓別人(尤其是未通過驗證的人)取得這些資訊仍有好處:一旦攻擊者辨識出哪些帳號是有效的,暴力破解密碼的成功率就大幅提高。因此,任何會洩漏有效使用者名稱是否存在、或讓人取得使用者清單的漏洞,都值得標記出來。
def process_authentication()
{
string username = read_string();
string password = read_string();
if(user_exists(username) == false)
{
write_error("User " + username " doesn't exist"); /* 錯誤訊息 A */
}
else
{
if(check_user_password(username, password))
{
write_success("User OK");
}
else
{
write_error("User " + username " password incorrect"); /* 錯誤訊息 B */
}
}
}程式先檢查使用者是否存在,不存在就回傳錯誤 A;存在則檢查密碼,密碼錯誤回傳錯誤 B。關鍵在於:兩個錯誤訊息不一樣。這個差異已足以讓攻擊者判斷哪些使用者名稱是有效的。
知道了有效的使用者名稱,攻擊者就更容易暴力破解出可用的憑證——只猜密碼,遠比同時猜使用者名稱與密碼簡單得多。
使用者列舉的價值不只在暴力破解。光是知道某個使用者名稱,就可能足以讓攻擊者發動一次成功的社交工程攻擊,誘使該使用者交出密碼或其他敏感資訊。