基于表单的网站身份验证

我们认为 Stack Overflow 不应该只是解决非常具体的技术问题的资源,而且还应该提供有关如何解决常见问题变体的一般指南。“基于表单的网站身份验证”应该是此类实验的一个很好的主题。

它应包括以下主题:

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

它不应该包括以下内容:

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

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

  1. 建议子主题
  2. 提交有关该主题的好文章
  3. 编辑官方答案
有帮助吗?

解决方案

第一部分:如何登录

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

使用 HTTPS 还是不使用 HTTPS?

除非连接已经安全(即使用 SSL/TLS 通过 HTTPS 建立隧道),否则您的登录表单值将以明文形式发送,这使得窃听浏览器和 Web 服务器之间线路的任何人都能够读取通过的登录信息通过。这种类型的窃听是由政府例行进行的,但一般来说,除了这样说之外,我们不会提及“拥有”的电线:如果您要保护任何重要内容,请使用 HTTPS。

从本质上来说,唯一 实际的 防止登录期间窃听/数据包嗅探的方法是使用 HTTPS 或其他基于证书的加密方案(例如, 传输层安全协议)或经过验证和测试的挑战响应方案(例如, 迪菲-赫尔曼基于SRP)。 任何其他方法都可以轻松绕过 由窃听攻击者。

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

(不要)自行进行 JavaScript 加密/散列

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

虽然这是一个崇高的想法,但它本质上是无用的(并且可能是一个 安全缺陷)除非它与上述之一结合 - 也就是说,要么使用强加密来保护线路,要么使用经过尝试和测试的质询响应机制(如果您不知道那是什么,只需知道它是一个)数字安全中最难证明、最难设计、最难实施的概念)。

虽然确实对密码进行了哈希处理 有效对抗 密码泄露, ,它很容易受到重放攻击、中间人攻击/劫持(如果攻击者可以在不安全的 HTML 页面到达您的浏览器之前将一些字节注入到您的不安全的 HTML 页面中,他们可以简单地注释掉 JavaScript 中的哈希值),或暴力攻击(因为您向攻击者提供了用户名、盐和散列密码)。

验证码反人类

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

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

就我个人而言,我倾向于认为验证码很烦人,并且仅在用户多次登录失败并且限制延迟达到最大时才将其用作最后的手段。这种情况很少发生,足以让人接受,并且它增强了整个系统。

存储密码/验证登录

在近年来我们看到了所有广为人知的黑客攻击和用户数据泄露之后,这可能最终成为常识,但必须说的是:不要将密码以明文形式存储在数据库中。用户数据库经常会通过 SQL 注入遭到黑客攻击、泄露或收集,如果您存储原始的明文密码,那么您的登录安全性就会立即结束。

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

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

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

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

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

如果您不熟悉会话数据,其工作原理如下:单个随机生成的字符串存储在过期的 cookie 中,并用于引用存储在服务器上的数据集合(会话数据)。如果您使用 MVC 框架,这无疑已经得到处理。

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

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

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

就我个人而言,我喜欢对我定期访问的网站进行持久登录,但我知道如何安全地处理它们。如果您确信您的用户也知道这一点,那么您可以问心无愧地使用持久登录。如果不是 - 好吧,那么您可能会同意这样的理念:粗心对待登录凭据的用户如果遭到黑客攻击,后果自负。这也不像我们去用户家撕下所有那些贴在显示器边缘的、贴着密码的便利贴。

当然,有些系统无法承受 任何 账户被黑客入侵;对于此类系统,您无法证明持久登录是合理的。

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

  1. 首先,花一些时间阅读 模范倡议的文章 就此主题而言。您需要正确理解一堆元素,本文对每个元素都做了很好的解释。

  2. 只是重申最常见的陷阱之一, 不要将持久登录 Cookie(令牌)存储在您的数据库中,仅存储它的哈希值! 登录令牌与密码等效,因此如果攻击者掌握了您的数据库,他们就可以使用令牌登录任何帐户,就像它们是明文登录密码组合一样。因此,使用散列(根据 https://security.stackexchange.com/a/63438/5002 当存储持久登录令牌时,弱哈希就可以满足此目的。

第三部分:使用秘密问题

不要实施“秘密问题”. 。“秘密问题”功能是一种安全反模式。请阅读必读列表中链接 4 中的论文。你可以向莎拉·佩林(Sarah Palin)询问有关这个问题的问题,在她的雅虎!电子邮件帐户在之前的总统竞选期间遭到黑客攻击,因为她的安全问题的答案是......“瓦西拉高中”!

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

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

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

  • 任何比猜测密码更容易回答的问题。对于任何像样的密码来说,这就是你能想象到的所有问题

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

安全问题普遍存在的真正原因是,它们可以方便地节省无法访问电子邮件以获取重新激活代码的用户拨打几次支持电话的费用。这是以牺牲安全和莎拉·佩林的声誉为代价的。值得?可能不会。

第四部分:忘记密码功能

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

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

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

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

第五部分:检查密码强度

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

好吧,也许这个列表不是 典范 最常见的密码列表 任何 系统 任何地方, ,但这很好地表明,在没有强制实施的策略的情况下,人们会多么糟糕地选择密码。另外,当你将它与最近被盗密码的公开分析进行比较时,该列表看起来非常接近实际。

所以:由于没有最低密码强度要求,2% 的用户使用最常用的 20 个密码之一。意义:如果攻击者仅尝试 20 次,您网站上的 50 个帐户中就有 1 个将被破解。

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

为了对高熵密码的用户友好性提出令人耳目一新的看法,Randall Munroe 的 密码强度 xkcd 强烈推荐。

利用特洛伊亨特 我被盗了吗 API 检查用户密码与公共数据泄露中泄露的密码。

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

首先,看一下数字: 密码恢复速度 - 您的密码可以保存多久

如果您没有时间查看该链接中的表格,请参阅以下列表:

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

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

  3. 它需要 几乎没有时间 破解复杂的、符号、字母、数字、大小写的密码(如果是) 长度少于 8 个字符 (台式电脑可以在几天甚至几小时内搜索整个密钥空间最多 7 个字符)

  4. 然而,即使破解 6 个字符的密码也需要花费大量时间, 如果您每秒只能尝试一次!

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

一般来说,您有三种选择,它们都可以有效抵御暴力攻击 (以及字典攻击,但由于您已经采用了强密码策略,因此它们不应该成为问题):

  • 呈现一个 验证码 经过 N 次失败的尝试(非常烦人并且常常无效——但我在这里重复一遍)

  • 锁定账户 并在 N 次失败尝试后要求电子邮件验证(这是一个 拒绝服务 攻击等待发生)

  • 最后, 登录限制: :也就是说,在 N 次失败的尝试之后,在尝试之间设置一个时间延迟(是的,DoS 攻击仍然是可能的,但至少它们的可能性要小得多,而且实现起来要复杂得多)。

最佳实践#1: 随着失败尝试次数的增加而增加的短暂延迟,例如:

  • 1 次失败尝试 = 没有延迟
  • 2 次失败尝试 = 2 秒延迟
  • 3 次失败尝试 = 4 秒延迟
  • 4 次失败尝试 = 8 秒延迟
  • 5 次失败尝试 = 16 秒延迟
  • ETC。

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) 登录(和/或验证码验证的登录表单)通过,这样合法用户就不会被延迟 当攻击正在进行时. 。这样,非常不切实际的 DoS 攻击就变成了 极其 不切实际的攻击。

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

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

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

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

  • 他们不会选择一个用户并尝试 50,000 个最常见的密码(由于我们的限制,他们不能这样做),而是选择最常见的密码并针对 50,000 个用户进行尝试。这样,他们不仅可以绕过验证码和登录限制等最大尝试次数措施,而且成功的机会也会增加,因为最常见的密码 1 比 49.995 更有可能

  • 为每个用户帐户设置登录请求的间隔,例如间隔 30 秒,以隐藏在雷达之下

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

太抽象?让我重新表述一下:

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

我还发布了一个问题 更多细节以及关于如何避免棘手陷阱的非常好的讨论 抵御分布式暴力攻击

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

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

身份验证可以完全委托给单点登录服务,由另一个提供商负责收集凭据。这将问题推给了可信的第三方。Google 和 Twitter 都提供基于标准的 SSO 服务,而 Facebook 则提供类似的专有解决方案。

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

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

其他提示

最终文章

发送凭证

100% 安全地发送凭证的唯一实用方法是使用 SSL协议. 。使用 JavaScript 对密码进行哈希处理并不安全。客户端密码哈希的常见陷阱:

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

还有另一种安全方法称为 建议零售价, ,但它已获得专利(尽管它是 免费许可)并且很少有好的实现可用。

存储密码

切勿将密码以明文形式存储在数据库中。即使您不关心自己网站的安全性,也不会。假设您的某些用户将重复使用其网上银行帐户的密码。因此,存储散列密码,并丢弃原始密码。并确保密码不会出现在访问日志或应用程序日志中。OWASP 推荐使用Argon2 作为您新应用的首选。如果这不可用,则应使用 PBKDF2 或 scrypt。最后,如果以上都不可用,请使用 bcrypt。

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

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

安全问题

安全问题是不安全的 - 避免使用它们。为什么?任何安全问题的作用,密码都会更好。读 第三部分:使用秘密问题@Jens Roland 回答 在此维基百科中。

会话cookie

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

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

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

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

外部资源列表

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

我将继续提到 Mozilla 的提议 浏览器ID (或者更准确地说, 已验证的电子邮件协议)本着寻找未来更好的身份验证方法的升级路径的精神。

我将这样总结一下:

  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 等主要网站。任何个人都可以拥有自己的域名,因此可以充当自己的身份提供商。

这并不是严格意义上的“基于表单的网站身份验证”。但这是从当前基于表单的身份验证规范过渡到更安全的方式的努力:浏览器支持的身份验证。

我只是想分享这个我发现效果很好的解决方案。

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

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

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

诀窍是欺骗机器人认为它必须将数据插入到必填字段中,这就是我将输入命名为“电子邮件”的原因。如果您已经有一个正在使用的名为电子邮件的字段,您应该尝试将虚拟字段命名为其他名称,例如“公司”、“电话”或“电子邮件地址”。只需选择一些您知道不需要的内容,以及听起来人们通常认为填写网络表单合乎逻辑的内容即可。现在隐藏 input 使用 CSS 或 JavaScript/jQuery 的字段 - 无论什么最适合你 - 只是 设置输入 typehidden 否则机器人就不会上当。

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

例子:

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

如果是机器人: 机器人将看到一个类型为的字段 text 和一个名字 email (或者无论你怎么称呼它),并且会在逻辑上尝试用适当的数据填充它。它并不关心您是否使用一些花哨的 CSS 设计输入表单的样式,网络开发人员一直在这样做。无论虚拟字段中的值是什么,只要它大于 0 人物。

我在留言簿上结合使用了这种方法 验证码, ,从那以后我再也没有看到过任何垃圾邮件帖子。我之前曾使用过仅验证码的解决方案,但最终,它导致每小时大约有五个垃圾邮件帖子。在表单中添加虚拟字段已阻止(至少到目前为止)所有垃圾邮件的出现。

我相信这也可以很好地与登录/身份验证表单一起使用。

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

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

有创意!

我不认为上面的答案是“错误的”,但是有很大一部分身份验证没有涉及(或者更确切地说,重点是“如何实现 cookie 会话”,而不是“有哪些选项可用以及交易是什么” -offs”。

我建议的编辑/答案是

  • 问题更多地在于帐户设置而不是密码检查。
  • 使用双因素身份验证比更巧妙的密码加密方法安全得多
  • 不要尝试实现您自己的登录表单或数据库存储密码的存储,除非存储的数据在帐户创建和自我生成时毫无价值(即,Web 2.0样式,例如Facebook, 弗利克, , ETC。)

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

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

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

所以 ...

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

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

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

  1. Kerberos 和 SPNEGO - 具有可信第三方的单点登录机制 - 基本上是用户针对可信第三方进行验证。(注意,这绝不是不值得信任的 开放认证)

  2. 建议零售价 - 无需可信第三方的巧妙密码验证。但在这里,我们进入了“使用双因素身份验证更安全,即使成本更高”的领域

  3. SSL协议 客户端 - 为客户端提供公钥证书(所有主要浏览器都支持 - 但引发了客户端计算机安全性问题)。

最后,这是一个权衡——安全漏洞的成本与实施更安全方法的成本是多少。有一天,我们可能会看到一个合适的 公钥基础设施 被广泛接受,因此不再拥有滚动的身份验证表格和数据库。一天...

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

创建哈希值的速度越快,暴力检查器的工作速度就越快。因此,较慢的哈希值会减慢暴力破解的速度。对于较长的密码(8 位以上),缓慢的哈希算法将使暴力破解变得不切实际

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

Dropbox 技术博客 » 博客存档 » zxcvbn:现实的密码强度估计

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

我想添加一项我使用过的基于深度防御的建议。您不需要为管理员提供与普通用户相同的身份验证和身份验证系统。您可以在单独的 URL 上使用单独的登录表单,为授予高权限的请求执行单独的代码。这个人可能会做出对普通用户来说非常痛苦的选择。我使用过的一种方法是实际打乱管理员访问的登录 URL,然后通过电子邮件向管理员发送新 URL。立即停止任何暴力攻击,因为您的新 URL 可能任意困难(非常长的随机字符串),但您的管理员用户唯一的不便之处在于点击其电子邮件中的链接。攻击者甚至不再知道要发布到哪里。

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

关于点 第四部分:忘记密码功能 在第一个答案中,我会提出有关定时攻击的观点。

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

关于忘记密码表单,我想补充一点,使用一些延迟函数使成功和不成功查询之间的时间相等是一个好主意。

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

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

  • “在一个 公司的, 网络设置”,上述大多数(如果不是全部)可能不适用!

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

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

这种“认证+授权”服务可以通过多种不同的技术来提供,例如LDAP (微软开放目录), ,或 Kerberos。

从你的角度来看,你只知道这一点:那 任何人 谁合法地访问了您的网站 必须 伴随着[神奇的环境变异...]“令牌”。 ((IE。 缺乏这样的令牌必须是立即的理由 404 Not Found.)

代币的价值对你来说毫无意义, 但, 如果需要,“存在适当的方法”,您的网站可以“[权威地]询问了解的人(LDAP...等)”关于任何 和每个(!) 您可能有的问题。换句话说,你做 不是 利用自己 任何 “本土逻辑。”相反,您询问权威并隐含地信任其判决。

嗯 ...它是 相当 从“疯狂的互联网”中进行的精神转变。

使用 OpenID 连接 或者 用户管理的访问.

因为没有什么比根本不做更有效的了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top