如果帐户存在则向用户披露?

信息安全 验证 用户枚举
2021-08-24 10:39:12

有人告诉我,某人应该不可能检测到某个电子邮件地址是否被网站上的注册用户使用。因此,例如,当用户要求重置他的密码时,无论电子邮件是否存在于数据库中,您都应该说“密码已发送”。如果没有,人们可以使用此功能来检查谁是会员,还可以检查垃圾邮件列表的有效性等。

但我注意到如果您尝试注册同一电子邮件两次,Facebook 会显示“电子邮件已注册”。这是否意味着约定发生了变化?通知用户比透露帐户更重要?

4个回答

不告诉人们是否存在特定登录是一个相当古老的传统。这就是为什么 Unix 或 Windows 系统在询问用户凭据时,将使用通用的“错误的用户名或密码”消息来响应任何错误。这个想法来自一个相当老式的攻击设想:设想一个想要进入大型机的坏人,并成功地得到一个插入系统的串行终端,或者可能是调制解调器线路上的 telnet 接口。该攻击者将处于在线词典攻击的位置:他将尝试猜测授予访问权限的一对登录名+密码。像“root”这样的管理登录名通常比普通用户帐户受到更好的保护(“root”用户更擅长选择强密码,或者至少据推测如此),因此攻击者会尝试找到普通用户帐户,并且,特别是普通用户帐户

观看电影 War Games(从 1983 年开始)可以让您很好地了解当时的情况。

注意关键点:在上面的攻击场景中,攻击者想要至少获得一个账号,但在正常情况下无法获得,甚至不知道谁有账号。

现在是 2013 年,距离那部电影已经过去了 30 年。我们有服务器,每个人都可以免费注册并获得一个帐户。因此,获得一个帐户不再是攻击者的目标。相反,攻击者将希望访问具有已知身份的特定帐户。这是不一样的情况。上下文发生了变化。因此,旧的传说不一定适用。


无论如何,当用户尝试在 Facebook 上注册时,他希望该过程能够正常工作。此时,该过程可能仅因一个合理的原因而失败,即已使用的电子邮件地址。很难对用户隐藏这个事实......

如果我们想“保护”用户的电子邮件地址,那么注册过程必须这样:

  • 用户输入他所谓的电子邮件。
  • 一封电子邮件将发送到该地址,其中包含一次性注册链接;但是,如果电子邮件已经注册,则会发送一封电子邮件来解释该事实。响应网页上没有关于电子邮件是否已经存在于系统中的任何线索。
  • 用户通过电子邮件中的链接进行注册。

这样的过程将兼作电子邮件验证过程,所以这很好。然而,它有一些延迟(用户必须离开网站,打开他的电子邮件阅读器,然后等待收到的电子邮件),所以这对于购物网站来说可能是个问题(用户没有耐心,他们很容易去购物如果他们发现结帐过程太麻烦,请在其他地方)。此外,必须有一些护栏来避免这个注册系统被滥用成垃圾邮件机器。


我认为可以说,对于 Facebook 的维护者来说,让注册过程尽可能的顺畅和快捷用户的隐私更重要。真的,这会给谁带来惊喜?

可能需要考虑 PII 风险。可以安全地假设“每个人”都有 Facebook 帐户,因此披露任何一封已注册的特定电子邮件并不是什么大不了的事。

但是,请使用其他服务,例如“depression-help.com”或“it-burns-when-I-tinkle.net”。向公众发布特定人员/电子邮件已在该站点注册是一个问题。

此外,对于具有较小用户群的小型服务,披露用户名可以为攻击者提供额外信息,这些信息可能会破坏帐户,就像某部 1983 年的电影一样。

向@ThomasPornin 致敬,但我相信在某些情况下,就像我所建议的那样,值得做出关于不披露用户帐户名称/电子邮件的明智决定。

确实没有一种优雅的方法可以解决这个问题,让每个人都 100% 开心。如果您强制使用电子邮件地址作为用户名,则可以轻松确定拥有给定电子邮件地址的人是否是用户(隐私问题)。如果你允许任意用户名,你真的无法最终揭示给定用户名是否已经被使用,你真正能做的就是采取措施减慢试图发现有效用户名的用户的速度。

新用户注册是最难处理的问题,因为最终您将不得不优雅地处理用户名冲突这一事实无法回避。这是一个可能的选项:让用户输入电子邮件地址、建议的用户名和所需的密码。提交后,验证密码是否可接受,并通过电子邮件向用户发送验证 URL。

  • 如果电子邮件地址已被使用,但与不同的用户名相关联,请给该用户发送电子邮件,提醒他已经有一个帐户,并询问他是否要重置密码。

  • 如果电子邮件地址尚未使用,但用户名已使用,则通过电子邮件向用户发送一条错误消息,让他知道他需要选择不同的用户名,并且每次尝试之间必须等待越来越长的时间。

  • 如果电子邮件地址和用户名都是新的,请通过电子邮件向用户发送一个确认链接,该链接需要使用新的用户名和密码重新进行身份验证,然后才能正式生效。

  • 不允许两个用户拥有相同的用户名,假设您可以根据他们的密码识别一个或另一个。除此之外,如果两个用户可以共享相同的用户名,这意味着您永远不会因为登录尝试失败而锁定用户名,而不会影响两个用户。上帝保佑,如果有一天他们碰巧选择了相同的密码,所有的地狱都会崩溃。

  • 不要对用户名和公共身份使用相同的值。如果用户真的想要,您不一定必须主动阻止用户为两者输入相同的值,但默认值应该是允许用户(例如在消息论坛上)拥有一个公共昵称不一定与他们登录时使用的用户名有关。

  • 不要按顺序分配用户 ID。使用在注册时生成并验证为唯一的至少 31 个,最好是 62 个位随机值。31 位和 62 位值的好处是它们可以巧妙地转换为 6 位和 12 位字符的 base36 字符串。调试时,记住 6 位或 12 位小写字母和数字的字符串比记住 6-17 位十进制值要容易得多。最困难的部分是使用虚假的响应来响应指定无效用户 ID 的请求,但无法通过算法手段轻易地将其与真实用户 ID 响应区分开来。

请记住:您不能也不会 100% 成功阻止攻击者偶尔验证给定的用户 ID 或用户名是否有效。您的目标是使其尽可能缓慢和昂贵,而不会给您的真实用户带来不合理的负担。对于真实世界的模拟,请考虑 DVD 和蓝光区域代码。当一个播放器的价格超过 500 美元时,地区代码是阻止几乎所有人播放从另一个地区购买的电影的有效方法。现在您可以花 80 美元购买蓝光播放器,花 20 美元购买 HDMI 选择器并获得零钱,真的没有什么可以阻止电影爱好者购买两三个蓝光播放器(每个所需区域一个),堆叠启动它们,并通过 HDMI 开关运行它们。

对于例行登录,故意对这次登录尝试失败的原因含糊其辞,但同样要提前说明可能的原因……并为他们提供可以帮助他们的人的具体联系信息。跟踪失败的登录,如果登录尝试失败次数过多,则锁定帐户。

  • 不要直接告诉他们该帐户刚刚被锁定或当前被锁定......但不要羞于提及它是登录尝试可能失败的几个可能原因之一。保留帐户可能被尝试登录的用户锁定的事实对您的安全没有任何帮助。

  • 您不必因为登录尝试失败而半永久锁定帐户。在许多情况下,您可能不应该这样做,因为那么您将创建一个方便的拒绝服务攻击。如果一个帐户有太多不成功的登录尝试,您可以进行 1、6 或 24 小时的“软”锁定,此时锁定将自行解除。这是一种情况恕我直言,告诉用户“稍后再试”是合法的。

登录尝试失败时可能显示的示例错误消息:

您输入的用户名和/或密码未被接受。您可能输入了无效的用户名、使用了不正确的密码,或者尝试使用由于登录尝试失败次数过多而被锁定的帐户登录。如果帐户已被锁定,您可以联系_ __寻求帮助[或等待_小时让帐户自行解锁]。请注意,无论原因如何,对于所有失败的登录,此错误消息都是相同的。

不要告诉他们“出了点问题,请稍后再试”,除非问题会自行解决。它不会欺骗攻击者,并且会严重惹恼合法用户。这是我最讨厌的事情之一,并且在我的“开发人员以安全剧院的名义所做的可怕事情”列表的顶部附近。除了令人难以置信的烦人之外,如果某人的帐户遭到入侵,您希望他们做的最后一件事就是等到稍后再引起某人的注意。

如果您有相应的电子邮件地址,您可以寻找一个帐户,这是标准的 facebook 行为。这些天来,很多人都禁用了该选项,但这仍然是 facebook 出现的地方。

在进行论坛审核时,我经常使用该功能来收集有关新注册帐户是否是被禁止用户的注册帐户的信息。

网站泄露电子邮件地址或用户名是否真实是一种攻击匿名性的方式。我记得有人重新注册了一个使用 TOR 出口节点的 IP 的案例。通过他在 Facebook 上分享的信息,我能够告诉这个人他母亲的名字。获取信息的途径是通过四圈相互关联的昵称。

像这样的信息披露使http://www.spokeo.com/等公司更容易运营。

在保护隐私方面,您还应该考虑所有数据敏感。参加一个有 1000 名用户的论坛。用户使用昵称发布无害信息。用户使用与其真实身份相关联的电子邮件地址登录论坛。

对于 1000 个用户,我很有可能可以通过文体测量法识别出 1000 个用户中的哪一个是我正在搜索的人。如果我成功完成这项任务,我就会得到一个秘密昵称。

我现在可以对该昵称运行 google 搜索,也可以在其他数据库中搜索nickname@gmail.com。我还获得了更大的文本样本,以便更轻松地运行未来的文体攻击。

想要找到持不同政见者的政府级攻击者拥有查询大量网络服务以检查某些电子邮件地址是否存在的资源,也可以投资于良好的文体系统。

如果您想保护隐私,那么隐藏已注册的电子邮件地址是有意义的。