题 基于表单的网站身份验证的权威指南[关闭]


基于表单的网站身份验证

我们认为Stack Overflow不仅应该是非常具体的技术问题的资源,而且还应该是关于如何解决常见问题变化的一般指导原则。 “基于表单的网站身份验证”应该是这种实验的一个很好的主题。

它应包括以下主题:

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

它不应包括以下内容:

  • 角色和授权
  • HTTP基本身份验证

请帮助我们:

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

5002


起源


为什么要排除HTTP基本认证?它可以通过Ajax在HTML Forms中工作: peej.co.uk/articles/http-auth-with-html-forms.html - system PAUSE
HTTP Basic Auth具有(相对)难以使浏览器忘记的特性。如果您不使用SSL来保护连接(即HTTPS),那也是非常不安全的。 - Donal Fellows
我认为值得谈论基于HTTP的SSO会话(包括固定和劫持)cookie(安全和仅http标志) - symcbean
超级有用 HttpOnly cookie标志,它可以防止基于JavaScript的cookie被盗(XSS攻击的一个子集),也应该在某处提到。 - Alan H.
哇。冗长的答案,其中一些人的数十个赞成票,但没有人提到通过HTTP提供登录表单的常见错误。我甚至与那些说“但它提交到https:// ......”的人争论,当我问他们是否确定攻击者没有重写未加密的页面表格被提供时,他只是空白的目光。 - dzuelke


答案:


第一部分:如何登录

我们假设您已经知道如何构建登录+密码HTML表单,该表单将值POST到服务器端的脚本以进行身份​​验证。下面的部分将讨论声音实用auth的模式,以及如何避免最常见的安全陷阱。

HTTPS还是HTTPS?

除非连接已经安全(即通过HTTPS使用SSL / TLS进行隧道传输),否则您的登录表单值将以明文形式发送,这允许任何窃听浏览器和Web服务器之间的线路的人都可以在通过时读取登录信息通过。这种类型的窃听是由政府定期完成的,但总的来说,除了这样说之外,我们不会解决“拥有”的电话:如果您要保护任何重要信息,请使用HTTPS。

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

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

(不)滚动自己的JavaScript加密/散列

鉴于在您的网站上设置SSL证书的非零成本和感知技术难度,一些开发人员倾向于推出他们自己的浏览器内哈希或加密方案,以避免通过不安全的线路传递明文登录。

虽然这是一个崇高的思想,但它本质上是无用的(并且可以是一个 安全漏洞)除非它与上述之一结合 - 也就是说,要么使用强加密来保护线路,要么使用久经考验的质询 - 响应机制(如果你不知道那是什么,只要知道它是一个最难以证明,最难设计,最难实现的数字安全概念)。

虽然哈希密码确实如此  有效对抗 密码泄露,它很容易受到重放攻击,中间人攻击/劫持(如果攻击者在你的不安全的HTML页面到达浏览器之前可以注入几个字节,他们可以简单地注释掉JavaScript中的哈希),或暴力攻击(因为你正在向攻击者发送用户名,盐和哈希密码)。

CAPTCHAS反人类

验证码 旨在挫败一种特定类型的攻击:自动字典/强力试错,没有人类操作员。毫无疑问,这是一个真正的威胁,但有一些方法可以无缝地处理它,不需要CAPTCHA,特别是正确设计的服务器端登录限制方案 - 我们稍后会讨论它们。

知道CAPTCHA实现不是一样的;它们通常不是人类可以解决的,其中大多数实际上对机器人无效,所有这些对于廉价的第三世界劳动力都是无效的(根据 OWASP,目前血汗工厂的费率是每500次测试12美元),有些实施在某些国家可能在技术上是非法的(见 OWASP身份验证备忘单)。如果您必须使用验证码,请使用Google的 验证码,因为它定义为OCR-hard(因为它使用已经OCR错误分类的书籍扫描)并且非常努力地使用户友好。

就个人而言,我倾向于发现CAPTCHAS很烦人,并且当用户多次登录失败并且限制延迟时间最多时,将它们用作最后​​的手段。这种情况很少能够被接受,并且它会加强整个系统。

存储密码/验证登录

在我们近年来看到的所有高度公开的黑客攻击和用户数据泄漏之后,这可能最终是常识,但必须说明:不要在数据库中以明文形式存储密码。用户数据库通常会通过SQL注入被黑客入侵,泄露或收集,如果您要存储原始明文密码,那么即时游戏结束也是为了您的登录安全性。

因此,如果您无法存储密码,如何检查登录表单中登录的登录名+密码组合是否正确?答案是使用a进行散列 密钥推导函数。无论何时创建新用户或更改密码,您都会获取密码并通过KDF(例如Argon2,bcrypt,scrypt或PBKDF2)运行密码,将明文密码(“correcthorsebatterystaple”)转换为长而随机的字符串,这在您的数据库中存储更安全。要验证登录,请对输入的密码运行相同的哈希函数,这次传入salt并将生成的哈希字符串与存储在数据库中的值进行比较。 Argon2,bcrypt和scrypt已经将哈希值与哈希一起存储。看看这个 文章 在sec.stackexchange上获取更多详细信息。

使用salt的原因是因为散列本身是不够的 - 你需要添加一个所谓的'salt'来保护哈希 彩虹桌。 salt有效地防止两个完全匹配的密码被存储为相同的哈希值,从而防止在攻击者执行密码猜测攻击时在一次运行中扫描整个数据库。

加密哈希不应该用于密码存储,因为用户选择的密码不够强(即通常不包含足够的熵),并且密码猜测攻击可以在相对较短的时间内由访问哈希的攻击者完成。这就是使用KDF的原因 - 这些都是有效的 “伸展钥匙” 这意味着攻击者猜测的每个密码都涉及多次迭代哈希算法,例如10,000次,这使得攻击者的密码猜测速度慢了10,000倍。

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

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

如果您不熟悉会话数据,可以使用以下方法:单个随机生成的字符串存储在过期的cookie中,用于引用存储在服务器上的数据集合 - 会话数据。如果您使用的是MVC框架,那么这无疑已经得到了解决。

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

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

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

就个人而言,我喜欢定期访问的网站的持久登录,但我知道如何安全地处理它们。如果您确信您的用户知道相同的内容,则可以使用持久登录并保持良心。如果不是 - 那么,你可以赞同这样的理念:如果用户被黑客攻击,那么他们的登录凭证不小心的用户会自行处理。这并不像我们去我们用户的房子并撕下所有那些引人注目的Post-It笔记,上面还有他们在显示器边缘排列的密码。

当然,有些系统无法承受 任何 帐户被黑了对于这样的系统,你无法证明持久登录的合理性。

如果您决定实施持久登录cookie,请按以下步骤操作:

  1. 首先,花些时间阅读 Paragon Initiative的文章 就此主题而言。你需要正确地获得一堆元素,而且这篇文章很好地解释了每一个元素。

  2. 只是重申一个最常见的陷阱, 不要在您的数据库中存储持久的登录COOKIE(令牌),只有它的一大堆! 登录令牌是密码等效的,因此如果攻击者抓住您的数据库,他们可以使用令牌登录任何帐户,就像他们是明文登录密码组合一样。因此,使用散列(根据 https://security.stackexchange.com/a/63438/5002 存储持久登录令牌时,弱哈希将为此目的做好。

第三部分:使用秘密问题

不要实施'秘密问题'。 “秘密问题”功能是一种安全反模式。阅读MUST-READ列表中链接号4的论文。在雅虎之后,你可以向Sarah Palin询问这个问题。电子邮件帐户在之前的总统竞选期间被黑了,因为她的安全问题的答案是......“Wasilla High School”!

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

  • 一个'标准'秘密问题,如母亲的娘家姓或宠物

  • 一个简单的琐事,任何人都可以从他们的博客,LinkedIn个人资料或类似的东西

  • 任何比猜测密码更容易回答的问题。对于任何体面的密码,您可以想象的每一个问题

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

安全问题甚至存在于野外的真正原因是它们可以方便地节省来自无法访问其电子邮件以获得重新激活代码的用户的一些支持呼叫的成本。这是以牺牲安全性和Sarah Palin的声誉为代价的。值得?可能不会。

第四部分:忘记密码功能

我已经提到你为什么这么做了 从不使用安全问题处理忘记/丢失的用户密码;不言而喻,您绝不应该通过电子邮件向用户发送他们的实际密码。在这个领域至少还有两个需要避免的常见缺陷:

  1. 重启 一个忘记密码的自动生成的强密码 - 这样的密码很难记住,这意味着用户必须更改或写下来 - 比如,在显示器边缘的亮黄色Post-It上。不要设置新密码,只需让用户立即选择一个新密码 - 这也是他们想要做的事情。 (例外情况可能是用户普遍使用密码管理器来存储/管理通常无法记住的密码而不将其写下来)。

  2. 始终在数据库中散列丢失的密码代码/令牌。 再次,此代码是密码等效的另一个示例,因此必须进行哈希处理,以防攻击者抓住您的数据库。当请求丢失的密码代码时,将明文代码发送到用户的电子邮件地址,然后哈希,将哈希保存在数据库中 - 扔掉原来的。就像密码或持久登录令牌一样。

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

第五部分:检查密码强度

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

好吧,也许列表不是 典范 最常见的密码列表 任何 系统 任何地方,但它很好地表明,当没有强制执行的政策时,人们会选择密码的能力有多差。此外,当您将该列表与最近被盗密码的公开分析进行比较时,该列表看起来非常贴近家庭。

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

阻止这一点需要计算密码的熵,然后应用阈值。美国国家标准与技术研究院(NIST) 特刊800-63 有一套很好的建议。那,当结合字典和键盘布局分析(例如,“qwertyuiop”是一个错误的密码)时,可以 拒绝所有选定密码错误的99% 在18位熵的水平。简单计算密码强度和 显示视觉强度计 对用户来说是好的,但不够。除非强制执行,否则许多用户很可能会忽略它。

而且,对于高熵密码的用户友好性,Randall Munroe's 密码强度xkcd 强烈推荐。

第六部分:更多 - 或者:防止快速登录尝试

首先,看看数字: 密码恢复速度 - 密码会持续多长时间

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

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

  2. 它需要 几乎没有时间 破解字母数字9个字符的密码(如果是) 不区分大小写

  3. 它需要 几乎没有时间 破解复杂的符号和字母和数字,大写和小写密码,如果是的话 长度不到8个字符 (桌面PC可以在几天甚至几小时内搜索最多7个字符的整个密钥空间)

  4. 但是,如果破解一个6个字符的密码,则需要花费大量的时间, 如果你每秒只限一次尝试!

那么我们可以从这些数字中学到什么呢?好吧,很多,但我们可以专注于最重要的部分:阻止大量快速连续登录尝试的事实(即 蛮力 攻击)真的不是那么难。但要防止它  并不像看起来那么容易。

一般来说,你有三个选择对蛮力攻击都有效 (和字典攻击,但由于你已经采用强密码策略,它们应该不是问题)

  • 提出一个 CAPTCHA 在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最佳实践建议(来自MUST-READ列表的链接1),并且应该被认为是最佳实践,即使它是公认的限制性方面。

但是,作为经验法则,我会说:您的密码策略越强,您就越不会对延迟的用户造成错误。如果您需要强大的(区分大小写的字母数字+所需的数字和符号)9个以上的字符密码,您可以在激活限制之前为用户提供2-4次非延迟密码尝试。

DoS攻击这个最终登录限制方案将是 非常 不切实际的。作为最后的触摸,始终允许持久(cookie)登录(和/或验证CAPTCHA的登录表单)通过,因此合法用户甚至不会被延迟 而攻击正在进行中。这样,非常不切实际的DoS攻击变成了一个 非常 不切实际的攻击。

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

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

同样,更高级的攻击者会试图通过“传播他们的活动”来规避登录限制:

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

  • 他们不会挑选一个用户并尝试使用50.000最常用的密码(由于我们的限制而无法使用),他们会选择最常用的密码,然后尝试对抗50.000用户。这样,他们不仅可以解决CAPTCHA和登录限制等最大限度尝试措施,他们的成功几率也会提高,因为最常见的1号密码比49.995更容易发生。

  • 将每个用户帐户的登录请求间隔为30秒,以便潜入雷达

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

太抽象了?让我重新说一下:

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

我还发了一个问题 更多细节和如何避免棘手的pitfals的非常好的讨论 抵御分布式蛮力攻击

第八部分:双因素身份验证和身份验证提供程序

凭据可能会受到损害,无论是利用漏洞,密码被记录下来还是丢失,密钥被盗的笔记本电脑,还是用户登录钓鱼网站。可以使用双因素身份验证进一步保护登录,该身份验证使用带外因素,例如通过电话,SMS消息,应用程序或加密狗接收的一次性代码。一些提供商提供双因素身份验证服务。

身份验证可以完全委托给单点登录服务,其中另一个提供程序处理收集凭据。这会将问题推送给受信任的第三方。谷歌和Twitter都提供基于标准的SSO服务,而Facebook则提供类似的专有解决方案。

必读链接关于Web身份验证

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

3498



嗯,我真的不同意Captcha部分,是的,Captchas很烦人,它们可能会被破坏(除了recaptcha,但这几乎是人类无法解决的!)但这就像是说不要使用垃圾邮件过滤器,因为它有误报率低于0.1%..这个网站使用的是Captchas,它们并不完美,但是它们减少了相当数量的垃圾邮件而且根本就没有好的替代品 - Waleed Eissa
@Jeff:很遗憾听到你的回复有问题。我不知道关于这个答案有关于Meta的辩论,如果你问我,我很乐意自己编辑。删除我的帖子只是从我的帐户中删除了1200声誉,这会伤害:( - Jens Roland
“在发送身份验证令牌后,系统需要一种方法来记住您已经过身份验证 - 这个事实应该只存储在会话数据中的服务器端。可以使用cookie来引用会话数据。”不完全的。您可以(并且应该为无状态服务器!)使用加密签名的cookie。这是不可能伪造的,不会占用服务器资源,也不需要粘性会话或其他恶作剧。 - Martin Probst
“台式电脑可以在不到90天的时间内搜索最多7个字符的全键盘”具有最新GPU的机器可以在不到1天的时间内搜索完整的7个字符键空间。顶级GPU可以每秒管理10亿个哈希值。 golubev.com/hashgpu.htm  这导致了一些关于密码存储的结论,这些结论没有直接解决。 - Frank Farmer
我很惊讶没有提到CSRF保护...... - Flukey


最终文章

发送凭据

100%安全地发送凭证的唯一实用方法是使用 SSL。使用JavaScript来散列密码是不安全的。客户端密码散列的常见缺陷:

  • 如果客户端和服务器之间的连接未加密,那么您所做的就是 容易受到中间人攻击。攻击者可以替换传入的javascript以打破散列或将所有凭据发送到他们的服务器,他们可以听取客户端响应并完美地模仿用户等等。具有可信证书颁发机构的SSL旨在防止MitM攻击。
  • 服务器收到的散列密码是 不太安全 如果你不在服务器上做额外的冗余工作。

还有一种叫做的安全方法 SRP,但它已获得专利(尽管它是 免费许可并且很少有好的实现可用。

存储密码

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

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

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

安全问题

安全问题是不安全的 - 避免使用它们。为什么?安全问题,密码做得更好。读 第三部分:使用秘密问题 在 @Jens Roland回答 在这个维基。

会话cookie

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

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

如果要自动登录用户,可以设置持久性cookie,但它应与完整会话cookie不同。您可以设置用户已自动登录的附加标志,并且需要为真正的敏感操作登录。这对于希望为您提供无缝,个性化购物体验但仍保护您的财务详细信息的购物网站而言非常受欢迎。例如,当您返回访问亚马逊时,他们会向您显示一个看起来像您已登录的页面,但当您下订单(或更改您的送货地址,信用卡等)时,他们会要求您确认你的密码。

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

外部资源清单


387



鉴于最近围绕签名SSL证书的MITM漏洞(blog.startcom.org/?p=145因此,SSL和某种Challenge响应认证(SRP的替代品)的组合可能是更好的解决方案。 - Kevin Loney
很多这样的东西都是情境化的。我根本不会使用会话cookie。被劫持的cookie几乎总是服务器故障。中间的人/包嗅闻不常见 - Shawn
BCrypt Nuget套餐: nuget.org/List/Packages/BCrypt - Fabian Vilers
注1关于这个答案:它是一个草稿,要编辑为维基。如果你可以编辑这个,欢迎你。 - Peter Mortensen


首先,一个强烈的警告,这个答案不是最适合这个问题的答案。绝对不应该是最好的答案!

我将继续提及Mozilla的提议 BROWSERID (或者更准确地说,是 已验证的邮件协议)本着寻找未来更好的身份验证方法的升级途径的精神。

我会这样总结一下:

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

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


146



BrowserID链接已经死了 - Mehdi
该项目似乎被封存了......看 en.wikipedia.org/wiki/Mozilla_Persona - Jeff Olson


我以为我会分享这个我发现工作得很好的解决方案。

我称之为 虚拟场 (虽然我没有发明这个,所以不要相信我)。

简而言之:你只需将它插入你的 <form> 并在验证时检查它是否为空:

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

诀窍是欺骗机器人认为必须将数据插入必填字段,这就是为什么我将输入命名为“电子邮件”。如果您已经有一个名为email的字段,那么您应该尝试将虚拟字段命名为“company”,“phone”或“emailaddress”。只需选择一些您不需要的东西,以及人们通常认为可以填充到网络表单中的内容。现在隐藏了 input 使用CSS或JavaScript / jQuery的字段 - 无论什么最适合你 - 只是  设置输入 type 至 hidden 否则机器人不会因此而堕落。

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

例:

如果是人: 用户将看不到虚拟字段(在我的情况下命名为“email”)并且不会尝试填充它。因此,在发送表单时,虚拟字段的值仍应为空。

如果是机器人: 机器人将看到一个类型为的字段 text 和一个名字 email (或者你称之为的任何东西)并且逻辑上会尝试用适当的数据填充它。它并不关心你是否用一些奇特的CSS设计输入表格,网络开发人员一直这样做。无论虚拟场中的值是什么,只要它大于,我们就不在乎 0 字符。

我在留言簿上结合使用这种方法 CAPTCHA,从那以后我没有看过一个垃圾邮件帖子。我之前使用过CAPTCHA解决方案,但最终每小时产生了大约5个垃圾邮件。在表单中添加虚拟字段已停止(至少到现在为止)所有垃圾邮件都会出现。

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

警告:当然这种方法不是100%万无一失。机器人可以编程为忽略具有样式的输入字段 display:none 适用于它。您还必须考虑使用某种形式的自动完成功能的人(如大多数浏览器内置的!)来自动填充所有表单字段。他们可能也会选择一个虚拟场。

您也可以通过让虚拟区域可见但在屏幕边界之外可以稍微改变一下,但这完全取决于您。

要有创意!


120



这是一个有用的反垃圾邮件技巧,但我建议使用“电子邮件”以外的字段名称,否则您可能会发现浏览器自动填充填写它,无意中阻止了您网站的真正用户。 - Nico Burns
我还有其他几个使用 visibility:hidden 并且 position:absolute;top:-9000px 你也可以 text-indent 并且 z-index 在一些这些元素上,并将它们放在压缩的CSS文件名中,名称尴尬 - 因为机器人可以检测到1display:none`,现在它们检查一系列组合 - 我实际上使用这些方法,它们是交易的旧技巧。 +1 - TheBlackBenzKid
当视力受损的用户使用屏幕阅读器导航表格时会发生什么? - gtcharlie
这种技术有一个名称:蜜罐 en.wikipedia.org/wiki/Honeypot_(computing) - pixeline
无需内联样式。只需在字段中添加一个类(可能使用一个对机器人来说永远不会有任何意义的奇怪单词),并通过网站的CSS文件隐藏它。喜欢: <input type="text" name="email" class="cucaracha"> 在你的CSS中: .cucaracha { display:none; }。 - Ricardo Zea


我不认为上述答案是“错误的”,但有大量的认证没有涉及(或者更重要的是“如何实现cookie会话”,而不是“有哪些选项可用,什么是交易”取舍”。

我建议的编辑/答案是

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

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

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

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

所以......

首先,我们混淆了初始创建帐户(带密码)与 随后重新检查密码。如果我是Flickr并且是第一次创建您的站点,则新用户可以访问零值(空白Web空间)。如果创建帐户的人谎称他们的名字,我真的不在乎。如果我正在创建医院内联网/外联网的帐户,那么价值在于所有医疗记录,所以我  关心帐户创建者的身份(*)。

这是非常困难的部分。该 只要 体面的解决方案是一个信任的网络。例如,您作为医生加入医院。您创建一个托管在您的照片,护照号码和公钥的某个地方的网页,并使用私钥对它们进行哈希处理。然后,您访问医院,系统管理员查看您的护照,查看照片是否与您匹配,然后使用医院私钥对网页/照片哈希进行哈希处理。从现在开始,我们可以安全地交换密钥和令牌。任何信任医院的人都可以(有秘密酱BTW)。系统管理员也可以给你一个 RSA 加密狗或其他双因素身份验证。

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

  1. Kerberos和SPNEGO - 与受信任的第三方签署机制 - 基本上用户验证可信第三方。 (注意,这绝不是不可信任的 OAuth的

  2. SRP  - 没有受信任的第三方的一种聪明的密码验证。但在这里,我们进入了“使用双因素身份验证更安全的领域,即使这样更昂贵”

  3. SSL 客户端 - 为客户端提供公钥证书(在所有主流浏览器中都支持 - 但会引发有关客户端计算机安全性的问题)。

最后,这是一个权衡 - 安全漏洞的成本与实施更安全的方法的成本是多少。有一天,我们可能会看到一个正确的 PKI 被广泛接受,因此不再拥有自己的滚动认证表格和数据库。一天...


71



很难说出你在谈论的答案是“我不认为上述答案是”错误的“ - Davorak


散列时,不要使用快速哈希算法,如MD5(存在许多硬件实现)。使用像SHA-512这样的东西。对于密码,较慢的哈希值更好。

创建哈希值的速度越快,任何强力检查器都可以工作得越快。较慢的哈希因此会减慢暴力迫使。慢速哈希算法会使更长时间的密码(8位+)变得不切实际


48



SHA-512也很快,因此您需要进行数千次迭代。 - Seun Osewa
“不要使用快速哈希算法......慢速哈希更好” - 解释?文档? - one.beat.consumer
说明:创建哈希值的速度越快,任何强力检查器的工作速度就越快。较慢的哈希因此会减慢暴力迫使。慢速哈希算法会使更长时间的密码(8位+)变得不切实际 - NickG
更喜欢像bcrypt这样设计用于缓慢散列的东西。 - Fabian Nicollier


关于实际密码强度估计的好文章是:

Dropbox Tech Blog»博客存档»zxcvbn:真实的密码强度估算


46





关于身份验证系统我最喜欢的规则是:使用密码而不是密码。容易记住,难以破解。 更多信息: 编码恐怖:密码与通行短语


41





我想根据防御深度添加一个我使用过的建议。您不需要为常规用户提供与管理员相同的auth&auth系统。您可以在单独的URL上使用单独的登录表单,为要授予高权限的请求执行单独的代码。这个可以做出对普通用户来说完全痛苦的选择。我使用的一个实际上是加密管理员访问的登录URL并通过电子邮件向管理员发送新URL。由于您的新网址可能是任意困难(非常长的随机字符串),因此立即停止任何暴力攻击,但您的管理员用户唯一的不便是关注其电子邮件中的链接。攻击者不再知道POST到哪里。


20



电子邮件中的简单链接实际上并不安全,因为电子邮件不安全。 - David Spector
它与任何其他基于令牌的密码重置系统一样安全,但不是双因素。这几乎都是他们所有人。 - Iain Duncan


我不知道最好回答这个问题作为答案或评论。我选择了第一个选项。

关于poing 第四部分:忘记密码功能 在第一个答案中,我会指出时间攻击。

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

关于遗忘密码表格,我想补充说,使用一些延迟函数在成功和不成功查询之间等于时间是个好主意。

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


12





我想补充一点非常重要的评论:

  • “在一个 企业,  帧内 网络设置,“如果不是所有上述内容可能不适用!

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

当用户尽职地连接到上述网络时,他们的身份 ( “认证”) 是[已经......]“最终知道”,这是他们的许可 ( “授权”) 做某些事......比如......“访问这个网站。”

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

从您的角度来看,您只需知道:那 任何人 谁合法地在你的网站上结束 必须 伴随着[一个环境变量神奇地包含......]一个“令牌”。 ( 没有这样的代币必须是立即的理由 404 Not Found。)

令牌的价值对你没有意义, 但, 如果需要,“存在适当的手段”,您的网站可以“[权威地]询问知道(LDAP ......等)的人” 每一个(!) 你可能有的问题。换句话说,你做到了  利用自己 任何 “本土逻辑。”相反,你询问管理局并暗中信任其判决。

嗯......是的 相当 从“野蛮的互联网”转变为精神。


10



作为一个孩子,你在标点符号上跌倒了吗? :)我已经阅读了三次,我仍然迷失在你想要的地方。但如果您说“有时您不需要基于表单的身份验证”,那么您是对的。但考虑到我们正在讨论何时需要它,我不明白为什么这一点非常重要? - Hugo Delsing
我的观点是世界 外 公司与世界完全不同 内。  如果您正在构建一个可以访问“毛茸茸的网络”的应用程序,并且供公众普遍使用,那么您别无选择,只能推出自己的身份验证和授权方法。但是,在公司内部,到达那里的唯一方法是在那里或使用VPN,那么应用程序很可能不会 - 一定不 有 - “自己的”做这些事情的方法。该应用程序 必须 而是使用这些方法来提供一致的集中管理。 - Mike Robinson
即使是内部网也需要建筑物中的最低安全性。销售部门拥有机密的损益数字,而工程部门拥有机密的知识产权。许多公司限制跨部门或部门的数据。 - Sablefoste