为什么Django默认的验证后端在没有找到用户的情况抛出异常里要执行Set_password

黑客使用定时枚举的方式攻击Django,使其暴露内部存在的用户名,为此Django修复了这个Bug(#20760)Bug,具体方式见内文

为什么验证用户的时候,当用户不存在的时候(except UserModel.DoesNotExist) , 要执行UserModel().set_password(password) ,Django代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def authenticate(self, username=None, password=None, **kwargs):
    UserModel = get_user_model()
    if username is None:
        username = kwargs.get(UserModel.USERNAME_FIELD)
    try:
        user = UserModel._default_manager.get_by_natural_key(username)
    	if user.check_password(password):
        	return user
    except UserModel.DoesNotExist:
        # Run the default password hasher once to reduce the timing
        # difference between an existing and a non-existing user (#20760).
        UserModel().set_password(password)

注意这行代码上面的注释

Run the default password hasher once to reduce the timing difference between an existing and a non-existing user (#20760).

大概意思就是当用户存在的时候,执行check_password 校验密码需要一定的服务器时间,而当用户不存在时,程序会立马返回None ,这导致黑客可以利用返回的时间差别来探测用户是否存在,因此在用户不存在的情况下执行UserModel().set_password(password)使二者返回时间相近,增加了保护意识。此bug修复代号为(#20760),连接li以此记录备忘。

comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计