登录代码的时间问题
Timing issues with login code
虽然它可能不完全符合 "timing attack" 的定义,但我仍然对此感到担忧。
我有一个公开登录视图的金字塔应用程序。每当有人输入不存在的用户时,应用程序都会显示一条消息,指出 login/password 组合无效。当输入有效用户但密码无效时也会发生这种情况。
这样做的目的是避免向假设的攻击者提供有关用户帐户的任何信息。
问题是,在第二种情况下,由于必须检查密码是否有效,程序花费的时间明显更长。这有效地使上述方案无效,因为攻击者可以根据发布表单和错误消息之间经过的时间来猜测用户是否存在。
有没有办法缓解这个问题?还是直接保留验证码更好?
这是登录视图的代码。
@view_config(route_name='login', renderer='templates/login.mak')
@forbidden_view_config(renderer='templates/login.mak')
def login(request):
form = LoginForm(request.POST, meta={"csrf_context": request.session})
login = form.user.data
password = form.password.data
if request.POST:
if form.validate():
user = DBSession.query(Users).filter(Users.username == login).scalar()
if (user is not None) and checkUser(user, password):
headers = remember(request, login)
return HTTPFound(location="/", headers=headers)
else:
# The login failed: there is no such user, or the password is invalid.
raise exc.HTTPForbidden()
else:
raise exc.HTTPForbidden()
return {'form': form}
提前致谢。
时间问题源于if user is not None
检查,这将导致checkUser
不运行。您需要做一些工作,最好尽可能接近您在检查有效用户帐户时所做的工作量。
我会在你的 if 和补丁 checkUser
中删除 is None
检查,以便在案例 user = None
中也能正常工作。在那种情况下,您可能(取决于您对 checkUser
的实现)必须执行类似 Django is doing 的操作,即创建一个带有一些密码的空用户对象和 运行 密码散列器,所以你做的工作量大致相同。
(此答案(特别是 django 参考)部分基于 )
虽然它可能不完全符合 "timing attack" 的定义,但我仍然对此感到担忧。
我有一个公开登录视图的金字塔应用程序。每当有人输入不存在的用户时,应用程序都会显示一条消息,指出 login/password 组合无效。当输入有效用户但密码无效时也会发生这种情况。
这样做的目的是避免向假设的攻击者提供有关用户帐户的任何信息。
问题是,在第二种情况下,由于必须检查密码是否有效,程序花费的时间明显更长。这有效地使上述方案无效,因为攻击者可以根据发布表单和错误消息之间经过的时间来猜测用户是否存在。
有没有办法缓解这个问题?还是直接保留验证码更好?
这是登录视图的代码。
@view_config(route_name='login', renderer='templates/login.mak')
@forbidden_view_config(renderer='templates/login.mak')
def login(request):
form = LoginForm(request.POST, meta={"csrf_context": request.session})
login = form.user.data
password = form.password.data
if request.POST:
if form.validate():
user = DBSession.query(Users).filter(Users.username == login).scalar()
if (user is not None) and checkUser(user, password):
headers = remember(request, login)
return HTTPFound(location="/", headers=headers)
else:
# The login failed: there is no such user, or the password is invalid.
raise exc.HTTPForbidden()
else:
raise exc.HTTPForbidden()
return {'form': form}
提前致谢。
时间问题源于if user is not None
检查,这将导致checkUser
不运行。您需要做一些工作,最好尽可能接近您在检查有效用户帐户时所做的工作量。
我会在你的 if 和补丁 checkUser
中删除 is None
检查,以便在案例 user = None
中也能正常工作。在那种情况下,您可能(取决于您对 checkUser
的实现)必须执行类似 Django is doing 的操作,即创建一个带有一些密码的空用户对象和 运行 密码散列器,所以你做的工作量大致相同。
(此答案(特别是 django 参考)部分基于