如何实现"不正确的用户名/密码#34;使用Flask HTTP Auth提示Web服务?

时间:2014-08-12 14:49:51

标签: python web-services security authentication flask

我有一个客户端应用程序,它与Web服务交互以检索帐户信息。如果用户输错了用户名/密码,则需要通知用户。我正在修改Web服务以向我的客户端返回一些内容,以向用户提供输入错误的提示。

如何正确实现使用Python找不到Web服务的“用户名/密码”?

  • 我是否告诉用户用户名存在,但密码不正确?
  • 我是否告诉用户没有这样的用户名,但密码匹配了什么?
  • 我是否显示未找到通用用户名/密码组合?
  • 我是否针对不同情况使用不同的状态代码,或者提供带有错误的JSON有效负载?

到目前为止,这是我的代码:

from flask.ext.httpauth import HTTPBasicAuth

accounts = [
    ["user0",   "password0"],
    ["user1",   "password1"],

]

@app.route('/accountlist')
@auth.login_required
def accountlist()
    username  = auth.username();
    if ... : #check if accounts does not have the given username
        #notify the sender that there is no such username
        return Response('Not Authorized', 401, {'WWW-Authenticate': 'Basic'})
    else:
        #proceed to check password and retrieve/return account information

3 个答案:

答案 0 :(得分:1)

  
    

我是否显示未找到通用用户名/密码组合?

  

是。为什么你认为这是"泛型"?因为它是标准。这是正确的方法,因为黑客不能为用户名进行网络钓鱼。

答案 1 :(得分:1)

  

我是否告诉用户用户名存在,但密码不正确?

不,让用户知道用户名是正确的是user enumeration漏洞。您让攻击者知道哪些用户名有效,允许他们缩小目标范围。如果他们后来决定尝试暴力攻击,这将是有用的,因为他们已经知道用户名是正确的,现在他们只需要一个工作密码。

  

我是否告诉用户没有这样的用户名,但密码匹配了什么?

绝对不是。这意味着攻击者现在拥有有效的密码,并且可以使用您网站上的任何其他用户名枚举漏洞来尝试查找有效的用户名。另一个常见的用户名枚举位置是忘记密码表单 - 许多网站报告说没有这样的用户名允许攻击者改进他们的列表。或者,他们可以使用此密码并从中强制使用用户名,这可能是一项更容易的工作,因为用户名不应该从复杂中受益。

除此之外,您应该使用安全,缓慢的算法(例如bcrypt)存储您的密码并进行哈希处理。这应该意味着您无法实际检查是否有任何密码与输入的密码匹配。

  

我是否显示未找到通用用户名/密码组合?

是!

  

我是否针对不同情况使用不同的状态代码,或者提供带有错误的JSON有效负载?

您的JSON可以返回truefalse,让调用JavaScript知道身份验证是否成功。如果您开发过任何强力保护措施,则应通过在响应中引入延迟而不是硬锁定帐户来实现。硬锁定帐户会导致DoS攻击,因为攻击者可以通过反复使用错误的密码锁定有效帐户。出于这个原因,实际上只需要一个真/假响应来让用户知道它们是否成功。即使帐户被硬锁定,我也会返回false,但如果用户认为他们应该使用提供的密码进行访问,那么用户应该联系技术支持。

答案 2 :(得分:0)

您没有提到您正在服务的数据类型,但如果您正在处理财务或医疗保健数据:要么这样做,要么用户可以登录,要么他们不能,您不应该努力给他们有关原因的任何信息。

如果您愿意,可以告诉他们用户名不正确,但您无法建议其他用户名。当然,您无法提供有关密码可能出错的任何信息,只需告诉他们这是不正确的。

关于您提供的代码,我意识到您并没有真正要求编码建议,我仍然会进行大量的代码审查,并始终通过这些自己的身份验证方案来反复查看相同的问题。如果您的代码经过审核,审核员可能会发现以下问题:

  1. 您绝不能对密码进行硬编码。

  2. 您必须永远不要以明文形式保留密码,在收到密码时始终使用不可逆的哈希值(SHA-1或更高版本),并且只能使用哈希值

  3. 您的应用程序应该“失败关闭”,这意味着设置accountList()函数以在if语句之前和调用任何会引发异常的函数(如数据库)之前返回“未授权”访问)。在if statemnt中进行身份验证。这样,如果if语句调用的东西失败(比如数据访问或文件i / o中的异常),则用户无法登录。