基于表单的网站身份验证的权威指南


5370

网站的基于表单的身份验证

我们认为,堆栈溢出不仅应作为解决非常具体的技术问题的资源,而且还应作为解决常见问题的通用准则。“基于表单的网站身份验证”应该是此类实验的一个不错的主题。

它应包括以下主题:

  • 如何登入
  • 如何登出
  • 如何保持登录状态
  • 管理Cookie(包括建议的设置)
  • SSL / HTTPS加密
  • 如何储存密码
  • 使用秘密问题
  • 忘记的用户名/密码功能
  • 使用随机数来防止跨站点请求伪造(CSRF)
  • OpenID
  • “记住我”复选框
  • 浏览器自动完成用户名和密码
  • 秘密URL(受摘要保护的公共URL
  • 检查密码强度
  • 电子邮件验证
  • 还有更多关于 基于表单的身份验证 ...

它不应包含以下内容:

  • 角色和授权
  • HTTP基本认证

请通过以下方式帮助我们:

  1. 建议子主题
  2. 提交有关此主题的好文章
  3. 编辑官方答案

52
为什么要排除HTTP基本身份验证?它可以通过Ajax在HTML表单中运行:peej.co.uk/articles/http-auth-with-html-forms.html
系统暂停

55
HTTP Basic Auth具有(相对)难以使浏览器忘记的特性。如果您不将它与SSL一起使用以确保连接(例如HTTPS)的安全,那也是非常不安全的。
多纳研究员2010年

24
我认为值得讨论基于Cookie的会话(包括固定和劫持)cookie(仅安全和http标志)
symcbean 2011年

29
超级有用的HttpOnlycookie标志可以防止基于JavaScript的cookie盗窃(XSS攻击的子集),也应该在某处提及。
艾伦·H。

80
哇。冗长的答案,对其中的一些赞誉,但没有人提到通过HTTP提供登录表单的常见错误。我什至与那些说“但它提交到https:// ...”的人发生争执,当我问他们是否确定攻击者没有重写表单已送达的未加密页面时,只有空白的凝视。
dzuelke 2012年

Answers:


3761

第一部分:如何登录

我们假设您已经知道如何构建一个登录名+密码HTML表单,该表单将值发布到服务器端的脚本中以进行身份​​验证。以下各节将介绍合理的实用身份验证模式,以及如何避免最常见的安全陷阱。

要HTTPS还是不要HTTPS?

除非连接已经安全(即使用SSL / TLS通过HTTPS进行隧道连接),否则您的登录表单值将以明文形式发送,这使任何窃听浏览器和Web服务器之间链接的人都可以在通过时读取登录信息通过。这类窃听通常由政府执行,但总的来说,除了说这句话外,我们不会处理“自有”的窃听器:仅使用HTTPS。

本质上,防止登录期间窃听/数据包嗅探的唯一实用方法是使用HTTPS或其他基于证书的加密方案(例如TLS)或经过验证的测试挑战响应方案(例如Diffie-Hellman)的SRP)。窃听攻击者可以轻松地绕过任何其他方法

当然,如果您有点不切实际,也可以采用某种形式的两因素身份验证方案(例如Google Authenticator应用,物理“冷战风格”密码本或RSA密钥生成器加密狗)。如果正确应用,即使在不安全的连接下也可以使用,但是很难想象开发人员愿意实施两因素身份验证而不是SSL。

(请勿)自行编写JavaScript加密/哈希

考虑到(虽然现在可以避免)的成本以及在您的网站上设置SSL证书的技术难度,一些开发人员倾向于使用自己的浏览器内哈希或加密方案,以避免在不安全的网上传递明文登录信息。

尽管这是一个高尚的思想,但是除非与以上内容之一结合使用,否则它基本上是没有用的(并且可能是安全缺陷)-也就是说,要么通过强加密保护线路,要么使用经过验证的挑战响应机制(如果您不知道这是什么,只需知道它是数字安全中最难证明,最难设计和最难实现的概念之一)。

散列密码确实可以有效地防止密码泄露,但是它很容易受到重放攻击,中间人攻击/劫持(如果攻击者可以在不安全的HTML页面中注入一些字节,然后再到达您的网站)浏览器,他们可以简单地注释掉JavaScript中的哈希)或蛮力攻击(因为您同时向攻击者提供了用户名,盐和哈希密码)。

CAPTCHAS反人类

CAPTCHA旨在阻止一种特定的攻击类型:无需人工操作的自动词典/蛮力试错法。毫无疑问,这是一个真正的威胁,但是,有许多方法可以无缝处理它,不需要验证码(经过专门设计的服务器端登录限制方案),我们将在后面讨论。

知道CAPTCHA的实现不是完全一样的。它们通常不是人类可以解决的,大多数实际上对机器人无效,对廉价的第三世界劳动力而言它们都是无效的(根据OWASP,当前的血汗工厂收费标准是每500个测试12美元),某些实现可能是在某些国家/地区在技术上是非法的(请参阅OWASP身份验证备忘单)。如果必须使用CAPTCHA,请使用Google的reCAPTCHA,因为从定义上讲它是OCR硬的(因为它使用了已经被OCR误分类的书本扫描),并且会尽力使用户友好。

就个人而言,我倾向于发现CAPTCHAS令人讨厌,并且仅在用户多次登录失败且限制延迟已达到最大时才将其用作最后的手段。这种情况很少发生,无法接受,并且会增强整个系统。

存储密码/验证登录名

在近年来发生的所有广为人知的黑客和用户数据泄漏之后,这可能最终成为常识,但是必须指出:不要在数据库中以明文形式存储密码。用户数据库通常会通过SQL注入被黑客入侵,泄漏或收集,如果您存储的是原始的纯文本密码,那么对于登录安全性来说,这是即时游戏。

因此,如果您不能存储密码,如何检查从登录表单中过帐的登录名和密码组合是否正确?答案是使用密钥派生函数进行哈希处理。每当创建新用户或更改密码时,您都将获取密码并通过KDF(例如Argon2,bcrypt,scrypt或PBKDF2)运行它,将明文密码(“ correcthorsebatterystaple”)变成一个长的,随机的字符串,这样可以更安全地存储在数据库中。为了验证登录名,您对输入的密码运行相同的哈希函数,这次传入了salt并将结果哈希字符串与数据库中存储的值进行比较。Argon2,bcrypt和scrypt已经将盐与哈希一起存储。请查看sec.stackexchange上的本文以获取更多详细信息。

使用盐的原因是散列本身是不够的-您将要添加一个所谓的“盐”来保护散列免受彩虹表的侵害。Salt可以有效地防止将两个完全匹配的密码存储为相同的哈希值,从而防止在攻击者执行密码猜测攻击时一次扫描整个数据库。

密码哈希不能用于密码存储,因为用户选择的密码不够强(即通常不包含足够的熵),并且攻击者可以在较短时间内完成对密码的猜测攻击。这就是为什么使用KDF的原因-这些有效地“拉伸密钥”,这意味着攻击者猜测的每个密码都会导致哈希算法的多次重复,例如10,000次,这会使攻击者猜测密码的速度慢10,000倍。

会话数据-“您以Spiderman69登录”

服务器针对您的用户数据库验证了登录名和密码并找到匹配项后,系统需要一种方式来记住浏览器已通过身份验证。这个事实只应该存储在会话数据的服务器端。

如果您不熟悉会话数据,请按以下说明进行操作:将一个随机生成的字符串存储在到期的cookie中,并用于引用存储在服务器上的数据集-会话数据。如果您使用的是MVC框架,那么无疑已经进行了处理。

如果有可能,请确保会话cookie发送到浏览器时已设置了安全和HTTP Only标志。HttpOnly标志为通过XSS攻击读取cookie提供了一些保护。安全标志可确保Cookie仅通过HTTPS发送回,因此可以防止网络嗅探攻击。cookie的值不应是可预测的。如果提供了引用不存在的会话的cookie,则应立即替换其值以防止会话固定

第二部分:如何保持登录状态-臭名昭著的“记住我”复选框

永久登录Cookie(“记住我”功能)是一个危险区域;一方面,当用户了解如何处理它们时,它们与传统登录完全一样安全;另一方面,粗心的用户则面临巨大的安全风险,他们可能会在公用计算机上使用它们,却忘记了注销,并且可能不知道浏览器cookie是什么或如何删除它们。

就个人而言,我喜欢经常访问的网站的永久登录,但是我知道如何安全地处理它们。如果您确定用户知道相同的信息,则可以凭良心使用持久性登录。如果不是-很好,那么您可能会赞同这样一种哲学,即粗心的登录凭据的用户会在被黑客入侵时将其带到自己身上。这也不像我们去用户家并撕下所有由facepalm引发的Post-It便条一样,它们的密码也都已排列在显示器的边缘。

当然,某些系统承受不了任何帐户被黑客入侵的风险。对于此类系统,您无法证明拥有永久登录名是合理的。

如果您决定实施永久性登录cookie,请按以下步骤进行:

  1. 首先,花一些时间阅读Paragon Initiative关于该主题的文章。您需要正确处理一堆元素,并且本文在解释每个元素方面做得很好。

  2. 只是要重申最常见的陷阱之一,请勿将持久登录的Cookie(令牌)存储在您的数据库中,而只是将其作为哈希!登录令牌是等效的密码,因此,如果攻击者将您的手放在您的数据库上,他们可以使用令牌登录任何帐户,就像它们是明文登录密码组合一样。因此,在存储持久性登录令牌时,请使用哈希(根据https://security.stackexchange.com/a/63438/5002进行此操作,散列就可以达到目的)。

第三部分:使用秘密问题

不要实施“秘密问题”。“秘密问题”功能是一种安全反模式。从必读列表中的链接编号4中阅读论文。您可以在Yahoo!之后询问Sarah Palin的问题。该电子邮件帐户在上次总统竞选期间遭到黑客入侵,原因是对她的安全性问题的回答是“ Wasilla高中”!

即使有用户指定的问题,大多数用户也很可能会选择以下任一项:

  • “标准”秘密问题,例如母亲的娘家姓或最喜欢的宠物

  • 一个简单的琐事,任何人都可以从其博客,LinkedIn个人资料或类似内容中获取

  • 任何比回答他们的密码都容易回答的问题。对于任何体面的密码,这是您可以想象的每个问题

总而言之,安全性问题本质上在所有形式和变体上本质上都是不安全的,并且出于任何原因都不应在身份验证方案中使用。

甚至在野外还存在安全性问题的真正原因是,它们可以方便地节省一些无法访问其电子邮件以获取重新激活码的用户的一些支持电话的费用。这是以牺牲安全性和萨拉·佩林的声誉为代价的。值得?可能不是。

第四部分:忘记的密码功能

我已经提到了为什么您永远不应该使用安全性问题来处理忘记/丢失的用户密码。不用说,您永远不要通过电子邮件向用户发送其实际密码。在此字段中,至少要避免两个非常常见的陷阱:

  1. 不要忘记的密码重设为自动生成的强密码-众所周知,此类密码很难记住,这意味着用户必须更改密码或将其写下来-例如,在显示器边缘的亮黄色Post-It上。无需设置新密码,只需让用户立即选择一个新密码即可。(这可能是一个例外,如果用户普遍使用密码管理器来存储/管理通常不记下来就无法记住的密码)。

  2. 始终对数据库中丢失的密码代码/令牌进行哈希处理。再次,此代码是等效密码的另一个示例,因此必须进行哈希处理,以防攻击者使用您的数据库。当要求输入丢失的密码代码时,请将纯文本代码发送到用户的电子邮件地址,然后对其进行哈希处理,然后将哈希表保存在数据库中,然后丢弃原始密码。就像密码或永久登录令牌一样。

最后一点:请始终确保您输入“丢失的密码”的界面至少与登录表单本身一样安全,否则攻击者只会使用它来获取访问权限。确保您生成非常长的“丢失的密码”(例如,区分大小写的16个字母数字字符)是一个很好的开始,但是请考虑添加与登录表单本身相同的限制方案。

第五部分:检查密码强度

首先,您需要阅读这篇小文章进行现实检查:500个最常用的密码

好吧,也许该列表是不规范的最常见的密码列表上的任何系统的任何地方不断,但它的人多么糟糕会选择自己的密码时,有一个地方不执行政策一个很好的迹象。此外,将列表与最近对被盗密码进行公开分析相比,该列表看上去离家很近。

因此:在没有最低密码强度要求的情况下,2%的用户使用前20个最常用的密码之一。含义:如果攻击者仅获得20次尝试,则您网站上50个帐户中的1个将是可破解的。

要阻止这种情况,需要计算密码的熵,然后应用阈值。美国国家标准技术研究院(NIST)特殊出版物800-63有一组非常好的建议。当与字典和键盘布局分析结合使用时(例如,“ qwertyuiop”是错误的密码),可以以18位的熵级别拒绝所有错误选择的密码的99%。简单地计算密码强度并向用户显示视觉强度计是好的,但还不够。除非强制执行,否则很多用户很可能会忽略它。

为了使用户更轻松地使用高熵密码,强烈建议使用Randall Munroe的Password Strength xkcd

利用Troy Hunt的“我已拥有” API来检查用户密码,以防在公共数据泄露中泄露密码。

第六部分:更多内容-或:防止快速射击登录尝试

首先,请看一下数字:密码恢复速度-您的密码可以使用多长时间

如果您没有时间浏览该链接中的表,请参见以下列表:

  1. 它需要几乎没有时间来破解弱密码,即使你用算盘咔吧

  2. 如果不区分大小写,则几乎不需要时间来破解字母数字的9个字符的密码

  3. 如果密码的长度少于8个字符几乎不需要花费任何时间就可以破解复杂的,符号,字母和数字以及大小写的密码(台式PC可以在一个问题中最多搜索7个字符的整个密钥空间)天或什至数小时)

  4. 但是,如果您每秒只能尝试一次,则破解6个字符的密码将花费大量时间

那么我们可以从这些数字中学到什么呢?好了,但有很多,但是我们可以专注于最重要的部分:防止大量快速连续射击尝试(即强力攻击)确实并不那么困难。但是,正确地阻止它似乎并不容易。

一般来说,您有三种选择都可以有效地抵抗暴力攻击(和字典攻击),但是由于您已经在使用强密码策略,因此这不应该成为问题

  • 在N次失败尝试后提出验证码(令人讨厌并且经常无效-但我在这里重复我自己)

  • N次尝试失败后锁定帐户并要求电子邮件验证(这是等待发生的DoS攻击)

  • 最后,登录限制:也就是说,在N次失败尝试之后设置两次尝试之间的时间延迟(是的,仍然可能发生DoS攻击,但起跳的可能性要小得多,复杂得多)。

最佳实践1:尝试失败的次数越短,延迟时间越长,例如:

  • 1次尝试失败=无延迟
  • 2次尝试失败= 2秒延迟
  • 3次失败尝试= 4秒延迟
  • 4次尝试失败=延迟8秒
  • 5次尝试失败=延迟16秒
  • 等等

DoS攻击此方案非常不切实际,因为最终的锁定时间略大于先前锁定时间的总和。

需要说明的是:延迟不是将响应返回到浏览器之前的延迟。这更像是超时或不应期,在此期间完全不会接受或评估对特定帐户或特定IP地址的登录尝试。也就是说,正确的凭据不会在成功登录后返回,并且错误的凭据也不会触发延迟增加。

最佳做法2:中等长度的时间延迟会在N次失败尝试后生效,例如:

  • 1-4次失败尝试=无延迟
  • 5次尝试失败=延迟15-30分钟

DoS攻击此方案将是不切实际的,但肯定是可行的。同样,可能需要注意的是,如此长的延迟对于合法用户而言可能非常烦人。健忘的用户会不喜欢您。

最佳实践3:将两种方法结合使用-固定的短时延,在N次失败尝试后生效,例如:

  • 1-4次失败尝试=无延迟
  • 5次以上失败尝试= 20秒延迟

或者,具有固定上限的增加的延迟,例如:

  • 1次尝试失败= 5秒延迟
  • 2次尝试失败=延迟15秒
  • 3次以上失败尝试= 45秒延迟

此最终方案来自OWASP最佳实践建议(必读列表中的链接1),即使被认为是限制性的,也应被视为最佳实践。

根据经验,我会说:密码策略越强,对用户进行延迟的麻烦就越少。如果您需要强壮的(区分大小写的字母数字+所需的数字和符号)9个以上的字符密码,则可以在激活限制之前为用户提供2-4次无延迟的密码尝试。

DoS攻击这种最终的登录限制方案将是非常不切实际的。最后,始终允许持久(cookie)登录(和/或经过CAPTCHA验证的登录表单)通过,因此在攻击进行期间,合法用户甚至都不会受到延迟。这样,非常不切实际的DoS攻击就变成了极为不切实际的攻击。

此外,对管理员帐户进行更积极的限制是有意义的,因为这些是最有吸引力的切入点

第七部分:分布式蛮力攻击

顺便说一句,更高级的攻击者将尝试通过“传播其活动”来规避登录限制:

  • 在僵尸网络上分发尝试以防止IP地址标记

  • 他们将选择最普通的密码并针对50.000个用户尝试,而不是选择一个用户并尝试使用50.000个最常用的密码(由于我们的限制,他们无法这样做)。这样,它们不仅绕过了诸如CAPTCHAs和登录限制之类的最大尝试措施,而且成功的机会也增加了,因为最常见的数字1的可能性远大于49.995。

  • 间隔每个用户帐户的登录请求,例如相隔30秒,以潜入雷达

在这里,最佳做法是记录系统范围内失败登录的次数,并使用站点错误登录频率的运行平均值作为基础,然后对所有用户强加上限。

太抽象了?让我改一下:

假设您的网站在过去3个月中平均每天有120次错误登录。使用该值(运行平均值),您的系统可能会将全局限制设置为该值的3倍,即 24小时内360次失败尝试。然后,如果所有帐户的失败尝试总数在一天之内超过该次数(甚至更好,监视加速速率并以计算出的阈值触发),它将激活系统范围的登录限制-这意味着所有用户的延迟很短(不过,除了Cookie登录名和/或备用CAPTCHA登录名之外)。

我还发布了一个具有更多细节的问题,并就如何避免防御分布式蛮力攻击进行了很好的讨论。

第八部分:两方面身份验证和身份验证提供程序

凭据可能会受到威胁,无论是利用漏洞,写下或丢失密码,笔记本电脑的钥匙被盗,还是用户在钓鱼网站中输入登录名。可以使用两因素身份验证进一步保护登录,该因素使用带外因素,例如从电话,SMS消息,应用程序或软件狗接收到的一次性代码。几个提供程序提供两因素身份验证服务。

身份验证可以完全委派给单点登录服务,其他提供商在该处处理收集凭据。这将问题推送到受信任的第三方。Google和Twitter均提供基于标准的SSO服务,而Facebook提供类似的专有解决方案。

关于Web身份验证的必读链接

  1. OWASP身份验证指南 / OWASP身份验证备忘单
  2. Web上客户端身份验证的注意事项(麻省理工学院的研究论文)
  3. 维基百科:HTTP cookie
  4. 用于后备身份验证的个人知识问题:Facebook时代的安全性问题(非常可读的伯克利研究论文)

67
好吧,我不太同意验证码部分,是的,验证码很烦人并且可以被破坏(recaptcha除外,但是人类几乎无法解决!),但这就像说不要使用垃圾邮件过滤器,因为它具有不到0.1%的假阴性..这个网站使用的是验证码,虽然不是很完美,但是却减少了很多垃圾邮件,根本没有替代品
Waleed Eissa

235
@Jeff:很遗憾听到您的答复有问题。我不知道在Meta上有关于此答案的辩论,如果您需要我本人会很乐意自行编辑。删除我的帖子只是从我的帐户中删除了1200点信誉,这很伤人:(
Jens Roland

13
“发送身份验证令牌后,系统需要一种方法来记住您已通过身份验证-此事实仅应存储在会话数据的服务器端。cookie可用于引用会话数据。” 不完全的。您可以(并且应该针对无状态服务器使用!)使用经过加密签名的cookie。这是不可能伪造的,不会占用服务器资源,也不需要粘性会话或其他恶作剧。
Martin Probst

12
“台式机最多可以在90天内搜索FULL KEYSPACE最多7个字符”具有最新GPU的计算机可以在不到1天的时间内搜索整个7个字符的键空间。顶级GPU每秒可以管理10亿个哈希。 golubev.com/hashgpu.htm 这会导致一些有关密码存储的结论,这些结论未得到直接解决。
弗兰克·法默

9
我很惊讶没有提到CSRF保护...
Flukey

418

权威文章

发送凭证

唯一安全地发送凭据的实用方法是使用 SSL。使用JavaScript哈希密码是不安全的。客户端密码哈希的常见陷阱:

  • 如果客户端和服务器之间的连接未加密,那么您所做的一切就是 容易受到中间人攻击。攻击者可以替换传入的JavaScript来破坏哈希或将所有凭据发送到其服务器,他们可以侦听客户端的响应并完美地模拟用户,等等。等等。带有受信任证书颁发机构的SSL旨在防止MitM攻击。
  • 如果您不对服务器执行其他多余的工作,则服务器收到的哈希密码不太安全

还有另一种称为SRP的安全方法,但该方法已获得专利(尽管它是免费许可的),并且几乎没有好的实现方法。

储存密码

永远不要将密码以明文形式存储在数据库中。即使您不在乎自己网站的安全性,也不会。假设您的某些用户将重复使用其在线银行帐户的密码。因此,存储散列密码,然后丢弃原始密码。并确保密码未显示在访问日志或应用程序日志中。OWASP 建议将Argon2用作新应用程序的首选。如果不可用,则应改用PBKDF2或scrypt。最后,如果以上都不可用,请使用bcrypt。

散列本身也不安全。例如,相同的密码意味着相同的哈希值-这使哈希查找表成为一次破解大量密码的有效方法。而是存储加盐的哈希。盐是哈希之前附加在密码上的字符串-每个用户使用不同的(随机)盐。salt是一个公共值,因此您可以将它们与哈希一起存储在数据库中。看到更多信息,此处

这意味着您不能向用户发送他们忘记的密码(因为您只有哈希)。除非您对用户进行了身份验证,否则请不要重置用户密码(用户必须证明他们能够阅读发送到已存储(并经过验证)的电子邮件地址的电子邮件。)

安全问题

安全问题是不安全的-避免使用它们。为什么?任何安全问题都可以解决,密码更好。阅读@Jens Roland中的第三部分:使用秘密问题,在此Wiki中回答

会话cookie

用户登录后,服务器向用户发送会话cookie。服务器可以从cookie中检索用户名或id,但是没有其他人可以生成这样的cookie(TODO解释机制)。

Cookie可以被劫持:它们仅与客户端计算机其余部分和其他通信一样安全。可以从磁盘读取它们,嗅探网络流量,通过跨站点脚本攻击将其清除,从有毒的DNS中清除,以便客户端将其cookie发送到错误的服务器。不要发送持久性cookie。Cookies应该在客户端会话结束时(浏览器关闭或离开您的域)到期。

如果您想自动登录用户,则可以设置一个持久性cookie,但是它应与完整会话cookie不同。您可以设置用户已经自动登录并需要真正登录才能进行敏感操作的其他标志。这在想要为您提供无缝的,个性化的购物体验但仍保护您的财务细节的购物网站中很受欢迎。例如,当您再次访问亚马逊时,他们会向您显示一个看起来像您已登录的页面,但是当您下订单(或更改您的送货地址,信用卡等)时,他们会要求您确认你的密码。

另一方面,诸如银行和信用卡之类的金融网站仅包含敏感数据,不应允许自动登录或低安全性模式。

外部资源清单


1
考虑到最近围绕签名SSL证书的MITM漏洞(blog.startcom.org/?p=145),因此将SSL和某种质询响应身份验证(SRP的替代品)结合使用可能是一个更好的解决方案。
Kevin Loney

这些东西很多都是视情况而定。我倾向于根本不使用会话cookie。Cookie被劫持几乎总是服务器故障。中间的男人/小包嗅到那常见的东西
Shawn


1
关于此答案的注释1:它是草稿,将被编辑为Wiki。如果可以编辑,欢迎您。
彼得·莫滕森

如果我了解得很清楚,SRP特定于几个参与方
Webwoman

162

首先,强烈警告此答案并非最适合此确切问题的答案。绝对不是最好的答案!

我将继续本着寻找将来升级到更好的身份验证方法的精神,提及Mozilla提议的BrowserID(或更确切地说,是经过验证的电子邮件协议)。

我将以这种方式总结一下:

  1. Mozilla是一家非营利组织,其价值观与为该问题找到良好的解决方案非常吻合。
  2. 当今的现实是,大多数网站都使用基于表单的身份验证
  3. 基于表单的身份验证有一个很大的缺点,那就是网络钓鱼的风险增加。要求用户将敏感信息输入由远程实体控制的区域,而不是由其用户代理(浏览器)控制的区域。
  4. 由于浏览器是隐式受信任的(用户代理的整个想法是代表用户执行操作),因此它们可以帮助改善这种情况。
  5. 阻碍进展的主要动力是部署僵局。解决方案必须分解为可自行提供一些增量收益的步骤。
  6. 表示互联网基础结构中内置的身份的最简单的分散方法是域名。
  7. 作为表示身份的第二层,每个域管理自己的一组帐户。
  8. “帐户@域” 的形式简明扼要,并得到各种协议和URI方案的支持。当然,这种标识符最普遍地被认为是电子邮件地址。
  9. 电子邮件提供商已经是事实上的在线主要身份提供商。如果可以证明您控制了该帐户的关联电子邮件地址,那么当前的密码重置流程通常可以让您控制一个帐户。
  10. 提出“已验证电子邮件协议”是为了提供一种基于公钥加密的安全方法,用于简化向域B证明您在域A上拥有帐户的过程。
  11. 对于不支持经过验证的电子邮件协议的浏览器(当前所有浏览器),Mozilla提供了一个垫片,该垫片在客户端JavaScript代码中实现该协议。
  12. 对于不支持“已验证电子邮件协议”的电子邮件服务,该协议允许第三方充当受信任的中介,声称他们已经验证了用户对帐户的所有权。拥有大量这样的第三方是不理想的;此功能仅旨在允许升级路径,并且电子邮件服务本身最好提供这些声明。
  13. Mozilla提供自己的服务,像这样一个受信任的第三方一样工作。实施“已验证电子邮件协议”的服务提供商(即依赖方)可以选择是否信任Mozilla的主张。Mozilla的服务使用传统的发送带有确认链接的电子邮件的方式来验证用户的帐户所有权。
  14. 当然,服务提供商除了可能希望提供的任何其他身份验证方法外,还可以提供此协议作为选项。
  15. 此处寻求的最大的用户界面好处是“身份选择器”。当用户访问网站并选择进行身份验证时,他们的浏览器会向他们显示选择的电子邮件地址(“个人”,“工作”,“政治活动”等),以供他们在该网站中使用自己的身份。
  16. 在此过程中,寻求的另一个重要的用户界面优势是帮助浏览器更多地了解用户会话 -主要是他们当前登录的用户 -因此可以在浏览器镶边中显示该用户会话
  17. 由于该系统的分布式特性,它避免了锁定诸如Facebook,Twitter,Google等主要网站的情况。任何人都可以拥有自己的域,因此可以充当自己的身份提供者。

这不是严格的“网站基于表单的身份验证”。但是,这是从当前基于表单的身份验证规范过渡到更加安全的工作:浏览器支持的身份验证。


3
BrowserID链接已死
Mehdi Bounya,

该项目似乎已被封存。...参见en.wikipedia.org/wiki/Mozilla_Persona
Jeff Olson

138

我只是以为我会分享这个发现很好的解决方案。

我称它为虚拟字段(尽管我还没有发明这个,所以请不要相信我)。

简而言之:您只需要<form>在验证时将其插入您的系统并检查其为空即可:

<input type="text" name="email" style="display:none" />

诀窍是让机器人认为必须将数据插入必填字段,这就是为什么我将输入命名为“电子邮件”的原因。如果您已经使用了一个名为email的字段,则应尝试为该虚拟字段命名,例如“ company”,“ phone”或“ emailaddress”。只需选择您不需要的东西,听起来人们通常会发现逻辑上可以将其填写到Web表单中。现在,input使用CSS或JavaScript / jQuery(最适合您的方法)隐藏该字段-只是不要将输入设置为typehidden否则该机器人就不会喜欢它。

在验证表单(客户端或服务器端)时,请检查您的伪字段是否已填写,以确定它是由人工发送的还是由机器人发送的。

例:

如果是人类: 用户将不会看到虚拟字段(在我的情况下为“电子邮件”),也不会尝试填充它。因此,发送表单后,虚拟字段的值仍应为空。

如果是机器人,则机器人将看到一个类型为text,名称email(或称其为它的名字)的字段,并在逻辑上尝试用适当的数据填充它。不管您是否使用一些精美的CSS设置输入表单的样式,Web开发人员始终都会这样做。无论虚拟字段中的值是多少,只要它大于0字符,我们都不会在乎。

我在访客留言簿上将此方法与CAPTCHA结合使用,此后我再也没有看到过垃圾邮件。我以前使用过仅CAPTCHA的解决方案,但最终,它每小时产生大约5封垃圾邮件。在表单中添加虚拟字段已停止(至少到现在为止)所有垃圾邮件的出现。

我相信这也可以用于登录/身份验证表单。

警告:当然,这种方法不是100%可靠的。可以对Bot进行编程,以忽略display:none应用了样式的输入字段。您还必须考虑使用某种形式的自动完成功能(例如大多数浏览器都内置了这些功能)来为其自动填写所有表单字段的人。他们也可能会选择一个虚拟字段。

您还可以通过使虚拟字段可见但在屏幕的边界之外来稍微改变一下,但这完全取决于您。

有创造力!


33
这是一个有用的反垃圾邮件技巧,但是我建议您使用“电子邮件”以外的其他字段名称,否则您可能会发现浏览器会自动填充该字段,从而无意中阻止了网站的真实用户。
尼科·伯恩斯

8
我也有几个,这些使用visibility:hidden,也position:absolute;top:-9000px还可以做text-indent,也z-index对其中的一些元素,并将它们与尴尬名称压缩CSS文件名-因为机器人可以检测1显示:none`,他们现在检查的范围组合-我实际上使用了这些方法,它们是行业的老把戏。+1
TheBlackBenzKid 2012年

18
有视力障碍的用户使用屏幕阅读器浏览表单时会发生什么?
soycharliente 2012年

8
此技术的名称为:honeypot en.wikipedia.org/wiki/Honeypot_(计算)
pixeline 2012年

27
无需内联样式。只需在该字段中添加一个类(也许使用一个怪异的词,它对漫游器永远不会有任何意义),然后通过网站的CSS文件将其隐藏。像:<input type="text" name="email" class="cucaracha">和在您的CSS中:.cucaracha { display:none; }
里卡多·泽

81

我不认为上面的答案是“错误的”,但是有很多未涉及的身份验证(或者重点是“如何实现cookie会话”,而不是“可用的选项和交易方式”) -offs”。

我建议的修改/答案是

  • 问题更多在于帐户设置,而不是密码检查。
  • 使用双重身份验证比使用更聪明的密码加密方法安全得多
  • 不要尝试实现自己的登录表单或密码的数据库存储,除非所存储的数据在创建帐户和自行生成时即没有价值(即,Facebook,Flickr等Web 2.0样式)。

    1. 摘要式身份验证是所有主要浏览器和服务器都支持的基于标准的方法,即使通过安全通道也不会发送密码。

这避免了任何需要“会话”或cookie的需要,因为浏览器本身每次都会重新加密通信。这是最“轻巧”的开发方法。

但是,除了公共的低价值服务外,我不建议这样做。这是上述其他一些答案的一个问题-不要尝试重新实现服务器端身份验证机制-大多数主要浏览器都已解决此问题,并支持该问题。不要使用cookie。不要将任何内容存储在您自己的手动数据库中。只需询问每个请求,该请求是否已通过身份验证。其他所有内容都应由配置和第三方可信软件支持。

所以...

首先,我们混淆了最初创建帐户(使用密码)和随后重新检查密码的混乱。如果我是Flickr,并且是第一次创建您的网站,则新用户可以访问零值(空白网站空间)。我真的不在乎创建帐户的人是否在撒谎。如果我要创建医院Intranet / Extranet的帐户,则该值存在于所有医疗记录中,因此,我确实关心帐户创建者的身份(*)。

这是非常非常困难的部分。该唯一体面的解决办法是信任的网站。例如,您以医生身份加入医院。您创建一个网页,其中托管了您的照片,护照号码和公钥,并使用私钥对它们进行了哈希处理。然后,您访问医院,系统管理员查看您的护照,查看照片是否与您匹配,然后使用医院私钥对网页/照片哈希进行哈希处理。从现在开始,我们可以安全地交换密钥和令牌。信任医院的人也一样(有秘密调味品BTW)。系统管理员还可以为您提供RSA加密狗或其他两因素验证。

但是,这是一个很多麻烦的,而不是非常的Web 2.0。但是,这是创建可以访问非自行创建的有价值信息的新帐户的唯一安全方法。

  1. Kerberos和SPNEGO-与受信任的第三方的单点登录机制-基本上,用户会针对受信任的第三方进行验证。(注意,这绝不是不可信任的OAuth

  2. SRP-一种巧妙的密码身份验证,无需可信任的第三方。但是在这里,我们进入了“使用双重身份验证的安全性,即使这样更昂贵”

  3. SSL客户端-向客户端提供公钥证书(所有主要浏览器均支持-但对客户端计算机的安全性提出了疑问)。

最后,这是一个权衡–安全漏洞的成本与实施更安全方法的成本是什么?有一天,我们可能会看到适当的PKI被广泛接受,因此不再拥有自己的滚动式身份验证表单和数据库。一天...


29
很难说出您在“我不认为上述答案是“错误的””中
涉及的

55

进行哈希处理时,请勿使用MD5之类的快速哈希算法(存在许多硬件实现)。使用类似SHA-512的东西。对于密码,散列越慢越好。

创建散列的速度越快,任何暴力破解检查程序都可以越快地工作。较慢的哈希值将减慢蛮力。慢速哈希算法将使强行破解对于较长的密码(8位数字以上)不切实际


5
SHA-512的速度也很快,因此您需要进行数千次迭代。
Seun Osewa

5
“不要使用快速哈希算法...哈希越慢越好”-解释?文档?
one.beat.consumer 2012年

17
说明:创建散列的速度越快,任何暴力破解检查程序都可以越快地工作。较慢的哈希值将减慢蛮力。慢速散列算法对于较长的密码(8位数字及以上)将无法强制使用暴力破解
NickG 2013年

6
更像是bcrypt之类的旨在缓慢散列的东西。
Fabian Nicollier 2014年

4
如另一个答案中所述,“ OWASP建议将Argon2用作新应用程序的首选。如果不可用,则应改用PBKDF2或scrypt。最后,如果以上都不可用,请使用bcrypt。” MD5和任何SHA哈希函数都不应用于哈希密码。这个答案是不好的建议。
迈克(Mike)



25

基于深度防御,我想添加一个我使用的建议。对于管理员,您不需要具有与普通用户相同的auth&auth系统。您可以在单独的url上拥有单独的登录表单,从而为授予高特权的请求执行单独的代码。这一选择可能会给普通用户带来很大的痛苦。我曾经使用过的一种方法是实际上对管理员访问的登录URL进行加密,然后将新的URL发送给管理员。立即停止任何暴力攻击,因为您的新URL可能会非常困难(非常长的随机字符串),但是您的管理员用户唯一的不便便是关注其电子邮件中的链接。攻击者甚至不知道发布到哪里。


电子邮件中的简单链接实际上并不安全,因为电子邮件不安全。
David Spector

它与其他不是基于两个因素的基于令牌的密码重置系统一样安全。几乎所有这些。
伊恩·邓肯

17

我不知道最好是作为答案还是作为评论来回答。我选择了第一个选项。

关于poing 一个答案中的第四部分:忘记密码功能,我将重点介绍定时攻击。

在里面 记住您的密码”表格中,攻击者可能检查电子邮件的完整列表,并检测哪些电子邮件已注册到系统(请参阅下面的链接)。

关于“忘记密码”表格,我想补充一点,这是一个很好的主意,它可以通过一些延迟功能来使成功查询与失败查询之间的时间相等。

https://crypto.stanford.edu/~dabo/papers/webtiming.pdf


14

我想添加一个非常重要的评论:-

  • “在公司 内部网络环境中”,上述所有内容(如果不是全部)可能都不适用!

许多公司部署“仅供内部使用”的网站,这些网站实际上是恰好通过URL实现的“企业应用程序”。这些URL (可能...)只能在“公司的内部网络”中解析。(哪个网络神奇地包括了所有与VPN连接的“公路战士”。)

当用户忠实地连接到上述网络时,其身份(“身份验证”) [已经……]“已经确定”,以及他们的许可(“授权”)。进行某些事情(例如。 ..“访问此网站。”

可以通过几种不同的技术(例如LDAP (Microsoft OpenDirectory))提供此“身份验证+授权”服务。或Kerberos。

从您的角度来看,您仅知道这一点:在您的网站上合法结束的任何人都必须随附[一个环境变量,其中包含……。(,缺少此类令牌必须是404 Not Found。)

令牌的值对您没有意义,但是,如果需要的话,“适当的方式存在”,您的网站可以通过该方式“ [权威性地]向某人了解(LDAP ...等)”中的任何内容(!)。您可能有的问题。换句话说,您不会利用任何 “本土逻辑”。取而代之的是,您查询“权威”并暗中信任其裁决。

嗯......这是相当从精神开关“野生和毛茸茸的互联网。”


9
你小时候落在标点符号上吗?:)我已经读过三遍了,但我仍然迷失在您要提出的观点上。但是,如果您说“有时候您不需要基于表单的身份验证”,那么您是对的。但是考虑到我们正在讨论何时需要它,我不明白为什么要注意这一点很重要吗?
雨果·德辛

1
我的观点是,公司外部的世界与公司内部的世界完全不同 如果您构建的应用程序可以通过“大众网络”访问,并且可供公众大众使用,那么您别无选择,只能推广自己的身份验证和授权方法。但是,在公司内部,到达那里的唯一途径是使用VPN或使用VPN,那么应用程序很可能没有- 一定没有 -“自己的”方法来执行这些操作。该应用程序必须改用这些方法,以提供一致的集中式管理。
Mike Robinson

2
即使是内部网,也要求建筑物中的安全性最低。销售具有机密的盈亏数字,而工程则具有机密知识产权。许多公司跨部门或部门限制数据。
Sablefoste

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.