我正在开发我的网络应用程序的入职功能,并且在某些时候我要求新用户选择一个用户名。
当用户到达这一点时,我有他/她的电子邮件和一个通过 SMS 验证的手机号码,并且他/她已经通过了 Google 的 no CAPTCHA reCAPTCHA。
我需要检查用户选择的用户名是否已经存在,如果存在,则提示用户选择另一个用户名。
在浏览网页时,我遇到了一些页面,说实现此类功能还为攻击者提供了一个工具来检查用户名是否存在。
检查用户名是否存在的最佳做法是什么?
我正在开发我的网络应用程序的入职功能,并且在某些时候我要求新用户选择一个用户名。
当用户到达这一点时,我有他/她的电子邮件和一个通过 SMS 验证的手机号码,并且他/她已经通过了 Google 的 no CAPTCHA reCAPTCHA。
我需要检查用户选择的用户名是否已经存在,如果存在,则提示用户选择另一个用户名。
在浏览网页时,我遇到了一些页面,说实现此类功能还为攻击者提供了一个工具来检查用户名是否存在。
检查用户名是否存在的最佳做法是什么?
该消息来源说,在这种情况下避免用户枚举几乎是不可能的,并且延迟攻击者是您能做的最好的事情:
如果您是开发人员,您可能想知道如何保护您的网站免受此类攻击。好吧,尽管几乎不可能使帐户注册工具不受用户名枚举的影响,但是可以通过实施 CAPTCHA 机制来避免针对它的自动用户名枚举攻击。
但是,我可能错过了一些东西——我也很好奇其他人是否有更好的解决方案。
该系统真的会发生什么
那很糟。因此,您需要防止多个用户拥有相同的用户名。你通过检查来做到这一点。
这是您所看到的场景,以及如何防止有人恶意使用它。你在这里冒什么风险?
好的,这提供了更多的安全性,并且仍然可以防止用户的电子邮件和其他敏感信息泄露。但现在您想尝试减轻攻击。你是怎样做的?
这里有几种技术可以防止它,但到目前为止最好的是速率限制和通过 IP 记录的最大尝试。
当用户尝试注册时,他们只能如此快速地检查可用用户名。实际上,一个真实的人需要一两秒钟才能输入一个新的用户名。这使您可以进行一些简单的制衡。然而,这只有在他们尝试注册时才会真正发生。当用户攻击您并使用未注册的用户名时,所发生的一切就是他们已经注册了该用户名。那好吧。现在他们必须重新开始注册过程,您可以在这里查看。
现在攻击者已经暴露了自己并在 IP 级别被禁止。你知道这里发生了一些不好的事情,有一个可能已经闪现的用户名日志,最好还没有个人信息泄露。很好!
但是,现在您需要返回并注销所有为尝试查找其他帐户而创建的帐户。幸好你有这些日志!
当您不将帐户绑定到电子邮件时,您需要注意一个大缺陷:用户名可以预先注册并持有赎金。那么证明用户名的所有权是非常困难的。这让我们有人对您的系统进行不同类型的攻击,他们只是试图预先注册很多人的帐户并勒索他们的赎金。希望您有上述检查的日志,以便您可以尝试在行动中抓住它们。
您提到他们已经完成了电子邮件确认过程,因此此时处理它的另一种方法是将其链接到电子邮件。注册后,如果他们想更改电子邮件,则必须登录,然后发送带有电子邮件链接的请求以进行更改。这可以使用时间敏感令牌来完成。现在他们也可以有一个用户名来显示在网站上。由于显示名称可能重叠并且无法尝试使用该信息访问另一个帐户,因此此处的陷阱也得到了缓解,但电子邮件提供了对真实性的检查(可能还有某种物理标识符,如个人资料图片)
问题 当用户尝试登录时,他或她输入了他们的用户名。注册时,您会被告知是否使用了用户名。如果你找到一个被盗用的用户名,你可以尝试用它登录并可能破解它。
解决方案 1(引入了另一个问题):
如果用户必须使用电子邮件登录,那么知道是否使用了用户名将无济于事。您使用电子邮件登录,而不是用户名。因此,当您知道helloman
有用户名时,攻击者无法知道在登录表单中输入什么内容。但是,现在的问题是告诉用户是否接收了电子邮件。
如何通过电子邮件确认进行保护
注册时,不要告诉用户电子邮件是否被占用。相反,告诉他们已发送确认电子邮件。向他们发送电子邮件,如果该电子邮件之前已注册,请发送一封电子邮件,说明 1)他们的帐户已经存在,以及 2)有人试图注册他们的电子邮件。向用户保证他们的帐户是安全的。
如果尝试注册helloman@example.com
的人不是真正的 helloman,那么他们可能不会看到 helloman 的电子邮件收件箱。如果真正的 helloman 尝试使用已注册的电子邮件创建一个新帐户,那么他们将收到一封电子邮件,说明他们已经注册了一个帐户。这种方法的主要问题是,如果黑客设法破解了 helloman@example.com。但是,当今最常见的电子邮件系统非常安全,因此不必担心。此外,如果他们的帐户被黑客入侵,这不是您的问题。
允许用户(或攻击者)找出用户名是否存在被称为“用户名枚举”漏洞。这里总结得很好:
作为攻击者,如果我可以使用您的登录或忘记密码页面将我的列表从 10000 个目标缩小到 1000 个目标,我会的。
您可以将“注册页面”添加到该列表中。这有助于攻击者进行任何网络钓鱼活动或任何密码猜测攻击。如果 Bob 的妻子 Alice 可以在 Ashley Madison.com 上找到 bob@example.com 是否存在,这也是一个隐私问题。
基本上,如果您允许用户选择与他们的电子邮件分开的自己的用户名,那么为了防止用户枚举,您应该只允许使用电子邮件/密码登录,并简单地使用用户名作为识别网站上其他用户的一种方式。
这样说对不起,用户名foobar被占用,请选择另一个没有漏洞。
这是因为与电子邮件地址不同,这些用户名在世界上不会是全球唯一的。因此,当您说一个被占用时,不会侵犯用户隐私。另外,由于您不能直接使用用户名登录,因此不会产生用户枚举漏洞。
作为额外的奖励,这也使帐户恢复和注册过程更加简单(这总是有利于安全)。也就是说,不需要“忘记用户名”功能和“忘记密码”功能——因为他们使用他们会记住的电子邮件地址登录,这是他们唯一需要重新获得访问权限的事情,前提是他们仍然可以访问他们的电子邮件帐户。确保您阻止用户枚举您的电子邮件地址 - 请参阅此答案。
作为对此答案的更新,我注意到您说您不想使用电子邮件作为用户名,以防用户决定更改其电子邮件地址。如果在您的体系结构中使用“用户名”作为主键,我认为这是一个问题的唯一原因,因此对电子邮件地址(如果它是用户名)的任何更新都会导致需要每个链接表被更新。对此进行重新架构以使用独立的 PK 将是解决此问题的首选解决方案,而不是将用户名设为静态。(注意到我对你的原因有一个很大的假设。)