Django 的密码重置令牌方法是否安全?

信息安全 密码 哈希 密码管理 hmac
2021-08-16 12:49:42

我正在为 Web 应用程序实现密码重置功能,并正在考虑采用类似于Django的实现。

简而言之,Django 创建一个由时间戳和时间戳和用户 ID 的哈希组成的令牌。此哈希是 HMAC,用于验证时间戳或用户 ID 是否未被篡改。

除了时间戳之外,有关用户的信息(例如她的密码盐)也会被散列。这样,如果用户更改了她的密码,令牌就会失效,从而减少了攻击者的机会之窗。

令牌生成器的源代码可以在这里查看 这里是伪代码:

function make_token(user)
  timestamp = current timestamp (now)
  value =  timestamp + user.id + user.password
  hash = create_hmac("some secret", value)
  return timestamp + ":" + hash

function check_token(user, token)
  timestamp = token.split(":")[0]
  hash = token.split(":")[1]

  if timestamp is after expiration date
    return false

  value =  timestamp + user.id + user.password
  comparate = create_hmac("some secret", value)

  // if the hash has changed, the token has been tampered with or the user has 
  // changed their password. 
  if hash != comparate
    return false

  return true

这对我来说似乎是一个很好的解决方案。自 2008 年左右以来,运行 Django 的网站一直在这样做,我找不到任何关于漏洞的报告。

我做了一些研究,Hacker News上有人不喜欢这种方法。还有几张关于这个主题的表示关注。但是,我还没有找到一个具体的原因来解释为什么这可能是不安全的。

这是生成密码重置令牌的安全方法吗?如果不是,为什么?

1个回答

与“X 是否安全”的任何问题一样,在某种程度上,答案将是“这取决于您从安全角度来看的确切要求、您面临的威胁、应用程序的类型以及您将部署的环境”

然而,有了这个警告,我想说从安全角度来看,上面概述的方案听起来相对合理,而且绝对比我过去看到的许多密码重置功能要好。

您链接的错误报告描述了一个非常具体的场景(攻击者具有对服务器端代码和配置的特定部分的读取权限,但没有其他访问权限),这确实代表了一种风险,这是一个非常边缘的场景(对我来说)好像他们拥有该访问权限一样,在他们开始为用户生成虚假密码重置链接之前,他们可能会攻击其他东西。

来自 HN 线程的评论在本质上更笼统,除了 Thomas 对避免他在评论中描述的标准方法的计划的普遍不安之外,似乎没有描述对该计划的具体威胁。虽然他的观点是合理的,但这并不是说 Django 方案被破坏了,更多的是需要权衡取舍。