我最近有时间再次思考安全密码重置功能应该如何工作,首先是当我将此功能构建到
你看,遗忘密码的世界其实是一个相当神秘的世界。 有许多不同的、完全可以接受的观点,也有许多相当危险的观点。 作为最终用户,您很可能多次遇到过它们中的每一个; 因此,我将尝试使用这些示例来展示谁做得正确,谁做得不好,以及您需要重点关注什么才能在您的应用程序中获得正确的功能。
密码存储:散列、加密和(惊呼!)纯文本
在讨论如何存储密码之前,我们不能讨论如何处理忘记的密码。 密码以三种主要类型之一存储在数据库中:
- 简单的文字。 有一个密码列,以纯文本形式存储。
- 已加密。 通常采用对称加密(加密和解密均使用一个密钥),加密后的密码也存储在同一列中。
- 散列。 单向过程(密码可以进行哈希处理,但不能进行去哈希处理); 密码, 我愿意希望,后跟一个盐,每个盐都在自己的列中。
我们直接回答最简单的问题: 切勿以纯文本形式存储密码! 绝不。 一个漏洞
加密效果更好,但也有其弱点。 加密的问题是解密; 我们可以将这些看起来疯狂的密码转换回纯文本,当这种情况发生时,我们又回到了人类可读的密码情况。 这是怎么发生的? 解密密码的代码中存在一个小缺陷,使其公开可用 - 这是一种方法。 黑客可以访问存储加密数据的机器 - 这是第二种方法。 另一种方法是窃取数据库备份,并且有人还可以获得加密密钥,而该密钥的存储方式通常非常不安全。
这就引出了哈希。 散列背后的想法是它是单向的; 将用户输入的密码与其哈希版本进行比较的唯一方法是对输入进行哈希处理并进行比较。 为了防止来自彩虹表等工具的攻击,我们在过程中加入了随机性(阅读我的
关于散列与加密的快速争论:您需要加密而不是散列密码的唯一原因是当您需要以纯文本形式查看密码时,并且 你永远不应该想要这个,至少在标准网站情况下是这样。 如果您需要这个,那么很可能您做错了什么!
警告!
帖子下面有色情网站 AlotPorn 的部分截图。 它修剪得很整齐,所以海滩上没有什么是你看不到的,但如果它仍然可能引起任何问题,请不要向下滚动。
始终重置您的密码 从来没有 别提醒他
您是否曾被要求创建一个函数 提醒 密码? 退后一步,反向思考这个请求:为什么需要这个“提醒”? 因为用户忘记了密码。 我们真正想做的是什么? 帮他重新登录。
我意识到“提醒”这个词(经常)在口语中使用,但我们真正想做的是 安全地帮助用户重新上线。 由于我们需要安全性,因此提醒(即向用户发送密码)不合适的原因有两个:
- 电子邮件是一个不安全的渠道。 正如我们不会通过 HTTP 发送任何敏感信息(我们会使用 HTTPS)一样,我们也不应该通过电子邮件发送任何敏感信息,因为它的传输层不安全。 事实上,这比简单地通过不安全的传输协议发送信息要糟糕得多,因为邮件通常存储在存储设备上,系统管理员可以访问、转发和分发、恶意软件可以访问等等。 未加密的电子邮件是一个极其不安全的渠道。
- 无论如何,您不应该访问该密码。 重新阅读前面有关存储的部分 - 您应该拥有密码的哈希值(带有良好的强盐),这意味着您不应该能够以任何方式提取密码并通过邮件发送。
让我用一个例子来演示这个问题
显然,第一个问题是登录页面无法通过 HTTPS 加载,但网站还会提示您发送密码(“发送密码”)。 这可能是上述术语的口语使用的一个例子,所以让我们更进一步,看看会发生什么:
不幸的是,它看起来并没有好多少。 并通过电子邮件确认存在问题:
这告诉我们 usoutdoor.com 的两个重要方面:
- 该网站不会对密码进行哈希处理。 它们充其量是加密的,但很可能是以纯文本形式存储的; 我们没有看到相反的证据。
- 该网站通过不安全的通道发送长期密码(我们可以返回并一次又一次地使用它)。
解决这个问题后,我们需要检查重置过程是否以安全的方式完成。 执行此操作的第一步是确保请求者有权执行重置。 也就是说,在此之前我们需要进行身份检查; 让我们看一下,如果在没有首先验证请求者实际上是帐户所有者的情况下验证身份,会发生什么情况。
列出用户名及其对匿名的影响
这个问题最好用视觉来说明。 问题:
你有看到? 请注意“没有用户使用此电子邮件地址注册”的消息。 如果这样的网站确认的话,问题显然就会出现 可用性 用户使用该电子邮件地址注册。 宾果 - 你刚刚发现了你的丈夫/老板/邻居的色情癖!
当然,色情内容是隐私重要性的一个相当标志性的例子,但将身份与特定网站联系起来的危险比上述潜在的尴尬情况要广泛得多。 一种危险是社会工程学; 如果攻击者可以将某人与该服务相匹配,那么他将拥有可以开始使用的信息。 例如,他可能会联系冒充网站代表的人并请求提供更多信息,以试图承诺
这种做法还带来了“用户名枚举”的危险,即人们可以通过简单地进行组查询并检查对它们的响应来验证网站上是否存在整个用户名或电子邮件地址集合。 您是否有所有员工的电子邮件地址列表并需要几分钟时间来编写脚本? 然后你就知道问题是什么了!
还有什么选择呢? 事实上,它非常简单,并且在
在这里,Entropay 完全没有透露其系统中是否存在电子邮件地址 给不拥有该地址的人... 如果你 自己的 该地址并且系统中不存在,那么您将收到如下电子邮件:
当然,在某些可接受的情况下,某人 认为您已在网站上注册。 但事实并非如此,或者我是通过不同的电子邮件地址进行的。 上面显示的示例很好地处理了这两种情况。 显然,如果地址匹配,您将收到一封电子邮件,以便更轻松地重置密码。
Entropay选择的解决方案的精妙之处在于,身份验证是根据 电子邮件 在进行任何在线验证之前。 有些网站要求用户回答安全问题(更多内容见下文) 对 如何开始重置; 然而,这样做的问题是,您必须在提供某种形式的标识(电子邮件或用户名)的同时回答问题,这使得在不透露匿名用户帐户存在的情况下几乎不可能直观地回答。
通过这种方法有 小的 可用性降低,因为如果您尝试重置不存在的帐户,则不会立即得到反馈。 当然,这就是发送电子邮件的全部意义,但从真正的最终用户的角度来看,如果他们输入了错误的地址,他们只有在第一次收到电子邮件时才会知道。 这可能会给他带来一些紧张,但对于如此罕见的过程来说,这只是一个很小的代价。
另一个稍微偏离主题的说明:显示用户名或电子邮件地址是否正确的登录辅助功能也存在同样的问题。 始终使用“您的用户名和密码组合无效”消息来响应用户,而不是明确确认凭据的存在(例如,“用户名正确,但密码不正确”)。
发送重置密码与发送重置 URL
我们需要讨论的下一个概念是如何重置密码。 有两种流行的解决方案:
- 在服务器上生成新密码并通过电子邮件发送
- 发送包含唯一 URL 的电子邮件以使重置过程更轻松
尽管
但除此之外,第一点还有一个严重的问题——它 尽可能简化 恶意封锁帐户。 如果我知道在网站上拥有帐户的人的电子邮件地址,那么我可以随时通过重置密码来阻止他们; 这是轻而易举的拒绝服务攻击! 这就是为什么只有在成功验证请求者的权限后才应执行重置的原因。
当我们谈论重置 URL 时,我们指的是以下网站的地址 重置过程的这种特殊情况是独一无二的。 当然,它应该是随机的,不应该容易猜测,并且不应该包含任何指向帐户的外部链接,以便更容易重置。 例如,重置 URL 不应该只是像“Reset/?username=JohnSmith”这样的路径。
我们想要创建一个唯一的令牌,可以作为重置 URL 进行邮寄,然后与用户帐户的服务器记录进行匹配,从而确认帐户所有者实际上就是尝试重置密码的同一个人。 例如,令牌可以是“3ce7854015cd38c862cb9e14a1ae552b”,并与执行重置的用户 ID 和生成令牌的时间一起存储在表中(更多内容见下文)。 邮件发送时,包含“Reset/?id=3ce7854015cd38c862cb9e14a1ae552b”这样的URL,用户下载时,页面会提示token存在,确认用户信息后,允许用户更改token。密码。
当然,由于上述过程(希望)允许用户创建新密码,因此我们需要确保 URL 是通过 HTTPS 加载的。 不,
另外,对于重置 URL,您需要添加令牌时间限制,以便重置过程可以在一定的时间间隔(例如一小时内)内完成。 这可确保重置时间窗口保持在最小值,以便重置 URL 的接收者只能在这个非常小的窗口内进行操作。 当然,攻击者可以再次启动重置过程,但他们需要获取另一个唯一的重置 URL。
最后,我们需要确保这个过程是一次性的。 重置过程完成后,必须删除令牌,以便重置 URL 不再起作用。 前一点对于确保攻击者有一个非常小的窗口来操纵重置 URL 是必要的。 另外,当然,一旦重置成功,就不再需要令牌了。
其中一些步骤可能看起来过于多余,但它们不会影响可用性和 其实 提高安全性,尽管我们希望这种情况很少见。 99%的情况下,用户会在很短的时间内启用重置,并且在不久的将来不会再次重置密码。
验证码的作用
噢,验证码,这个让我们又爱又恨的安全功能! 事实上,与其说验证码是一种保护工具,不如说它是一种识别工具——无论你是人还是机器人(或自动化脚本)。 其目的是避免自动提交表单,当然, может 被用作破坏安全的尝试。 在密码重置的情况下,CAPTCHA 意味着重置功能不能被强制向用户发送垃圾邮件或尝试确定帐户的存在(当然,如果您遵循有关部分的建议,则这是不可能的)验证身份)。
当然,验证码本身并不完美; 其软件“黑客攻击”并取得足够成功率(60-70%)的先例有很多。 此外,我的帖子中显示了一个解决方案
让我们看一下 PayPal 的例子:
在这种情况下,只有解决验证码后才能开始重置过程,因此 理论上 不可能使该过程自动化。 理论上。
然而,对于大多数 Web 应用程序来说,这有点过分了 究竟 代表可用性下降 - 人们只是不喜欢验证码! 此外,如有必要,您可以轻松返回验证码。 如果服务开始受到攻击(这是日志记录派上用场的地方,稍后会详细介绍),那么添加验证码再简单不过了。
秘密问题和答案
通过我们考虑的所有方法,我们只需访问电子邮件帐户即可重置密码。 我说“只是”,但是,当然,访问他人的电子邮件帐户是非法的。 必须 是一个复杂的过程。 然而
事实上,上面的链接是关于莎拉佩林的雅虎被黑客攻击的。 有两个目的; 首先,它说明了攻击(某些)电子邮件帐户是多么容易,其次,它说明了如何恶意使用不良安全问题。 但我们稍后会再讨论这个问题。
XNUMX% 基于电子邮件的密码重置的问题在于,您尝试重置的网站帐户的完整性将 XNUMX% 取决于电子邮件帐户的完整性。 任何有权访问您的电子邮件的人 可以访问任何只需接收电子邮件即可重置的帐户。 对于此类帐户,电子邮件是您在线生活的“所有大门的钥匙”。
降低这种风险的一种方法是实施安全问答模式。 毫无疑问您已经见过它们:选择一个只有您可以回答的问题 有 知道答案,然后当您重置密码时,系统会要求您提供答案。 这增加了尝试重置的人确实是帐户所有者的信心。
回到莎拉佩林:错误在于她的安全问题的答案很容易找到。 特别是当你是一个如此重要的公众人物时,有关你母亲的婚前姓氏、教育背景或某人过去可能居住的地方的信息并不是那么秘密。 事实上,几乎任何人都可以找到其中的大部分内容。 这就是莎拉身上发生的事情:
黑客 David Kernell 通过查找佩林的背景详细信息(例如她的大学和出生日期),然后使用雅虎的忘记密码恢复功能,获得了佩林帐户的访问权限。
首先,这是雅虎的设计错误。 - 通过指定这些简单的问题,该公司基本上破坏了安全问题的价值,从而破坏了对其系统的保护。 当然,重置电子邮件帐户的密码总是比较困难,因为您无法通过向所有者发送电子邮件(没有第二个地址)来证明所有权,但幸运的是,如今创建这样的系统的用途并不多。
让我们回到安全问题 - 有一个选项允许用户创建自己的问题。 问题是这会导致非常明显的问题:
天空是什么颜色?
当使用安全问题来识别时,会让人感到不舒服的问题 人 (例如,在呼叫中心):
圣诞节我和谁睡了?
或者坦率地说愚蠢的问题:
“密码”怎么拼写?
当涉及到安全问题时,用户需要自救! 换句话说,安全问题应该由网站本身确定,或者更好的是,由网站提出 系列 用户可以选择的安全问题。 而且选择并不容易 一; 理想情况下,用户应该选择两个或更多安全问题 注册帐户时,然后将用作第二个识别通道。 拥有多个问题可以增加验证过程中的信心,并且还提供了添加随机性的能力(并不总是显示相同的问题),并且在实际用户忘记密码的情况下提供了一些冗余。
什么是好的安全问题? 这受到几个因素的影响:
- 他肯定是 简短的 ——问题必须清晰明确。
- 答案必须是 具体 ——我们不需要一个人可以给出不同答案的问题
- 可能的答案应该是 各种各样的 - 询问某人最喜欢的颜色只会得到一小部分可能的答案
- 搜索 答案一定很复杂 - 如果答案很容易找到 任何 (记住身居高位的人),那他就不好了
- 答案必须是 DC 及时 - 如果你问某人最喜欢的电影,那么一年后答案可能会不同
碰巧有一个专门提出好问题的网站,叫做
让我演示一下 PayPal 如何实施安全问题,特别是该网站在身份验证方面所做的努力。 上面我们看到了启动该过程的页面(带有验证码),这里我们将展示输入电子邮件地址并解决验证码后会发生什么:
结果,用户收到以下信件:
到目前为止,一切都很正常,但以下是此重置 URL 背后隐藏的内容:
因此,安全问题就发挥了作用。 事实上,PayPal还允许您通过验证信用卡号来重置密码,因此有一个许多网站无法访问的额外渠道。 我只是无法在不回答的情况下更改密码 两 安全问题(或不知道卡号)。 即使有人劫持了我的电子邮件,他们也无法重置我的 PayPal 帐户密码,除非他们知道更多有关我的个人信息。 什么信息? 以下是 PayPal 提供的安全问题选项:
就搜索的难易程度而言,学校和医院的问题可能有点不确定,但其他问题还不错。 但是,为了增强安全性,PayPal 需要额外的身份验证 变化 安全问题的答案:
PayPal 是安全密码重置的一个相当乌托邦的例子:它实现了验证码来减少暴力攻击的危险,需要两个安全问题,然后需要另一种完全不同的身份验证来更改答案 - 而且是在用户之后已经登录。 当然,这正是我们所要的 预期 来自贝宝; 是一家处理大额资金的金融机构。 这并不意味着每次密码重置都必须遵循这些步骤(大多数时候这是多余的),但对于安全性至关重要的情况来说,这是一个很好的例子。
安全问题系统的便利之处在于,如果您还没有立即实施,可以在以后根据资源保护级别需要时添加。 Apple 就是一个很好的例子,它最近才实施了这种机制 【2012年写的文章】。 当我开始在 iPad 上更新应用程序时,我看到了以下请求:
然后我看到一个屏幕,我可以在其中选择几对安全问题和答案,以及救援电子邮件地址:
至于 PayPal,问题是预先选定的,其中一些问题实际上相当不错:
三个问题/答案对中的每一个都代表一组不同的可能问题,因此配置帐户的方法有很多种。
回答安全问题时需要考虑的另一个方面是存储。 在数据库中拥有纯文本数据库会带来与密码几乎相同的威胁,即暴露数据库会立即暴露该值,不仅使应用程序面临风险,而且可能使使用相同安全问题的完全不同的应用程序面临风险(再次出现)
安全问题和答案的最后一个方面是它们更容易受到社会工程的攻击。 尝试直接提取他人帐户的密码是一回事,但开始讨论密码的形成(一个流行的安全问题)则完全不同。 事实上,你可以很好地与某人沟通他们生活中的许多方面,这些方面可能会提出秘密问题,而不会引起怀疑。 当然,安全问题的关键就在于它与某人的生活经历有关,所以容易记住,这就是问题所在—— 人们喜欢谈论他们的生活经历! 对此您无能为力,除非您选择此类安全问题选项,以便它们 小 可能可以通过社会工程来删除。
[待续。]由于宣传
维迪斯娜 提供可靠的
来源: habr.com