我自己的身份验证方案有什么问题?

信息安全 Web应用程序 验证 javascript
2021-08-20 15:37:37

所以我想为 web-app 服务器编写自己的身份验证方案,如下所示。我认为无论出于安全性还是成本效益的原因,这都是一个坏主意,而且我知道传统智慧是使用现有的库,但我很乐意指出我到底哪里出错了,因为这个方案似乎既安全且易于构建。

在 Pseudo-API 中,我会回复以下内容:

  1. POST /login,signup (+username, passwd) -> 为这个用户创建并返回令牌。(将用户<->令牌关系保存在服务器上。)

  2. POST /logout (+token) -> 在服务器上为该用户销毁令牌。(销毁服务器上的用户<->无关系。)

  3. POST /any-action (+token) -> 如果令牌正确则执行操作。(用户和令牌匹配服务器上的用户<->令牌。)

以上是不安全的范例吗?

3个回答

是的,这是不安全的。

您的设计似乎容易受到跨站点请求伪造(CSRF 也称为 XSRF)攻击(需要添加一个CSRF 令牌以及与表单一起显示并存储在会话 cookie 中的所有 POST 操作)。基本上,如果用户在登录您的网站时访问其他网站(电子邮件、论坛、博客),他们的浏览器可能会被迫(通过 javascript、秘密表单)向您的网站发出意外的 POST 请求,执行某些操作我不想要。

你的方案也不是特别具体。

  • 如何处理密码(bcrypt 或 PBKDF)?或者至少是一个盐渍哈希?他们是否通过恒定时间字符串比较进行检查?
  • 在传输过程中如何通过网络保护数据(HTTPS?),
  • 如何从数据库中插入/提取数据?到处都是准备好的语句(也称为参数化查询)?(太好了!)或者您是否使用包含用户输入的 SQL 命令执行字符串(易受攻击!)?
  • 令牌是如何存储在浏览器中的(安全的仅 HTTP cookie?)

很可能它们也可能是实施中的其他缺陷。

您提供的不是身份验证协议;它只是一个概念,即会话令牌的概念。

简单来说:

  • 服务器对客户端进行身份验证,并将密钥发送回该客户端(会话令牌)。
  • 当客户端返回时,它会向服务器显示令牌以证明它与之前的客户端相同。
  • 客户端可以请求服务器忘记令牌(当然,与您显示的相反,“注销”请求也应该包括令牌,否则任何人都可以注销其他人)。

这个概念没有错,只要你了解它的局限性。例如,它本质上依赖于客户端/服务器通信既是机密的(因此没有被动攻击者窃听令牌),又是弹性的(因此没有主动攻击者可以在身份验证后劫持连接)。简而言之,SSL(即HTTPS)是强制性的。

我同意你的看法:这个方案似乎很容易构建。但请注意:这是一种错觉。事实上,即使概念清晰简单,构建一个安全的认证会话系统也并非易事。构建一个可以工作的系统很容易,并且可以测试;但是,安全性无法进行测试,并且比通常假设的要多得多。

实现可能会以多种方式脱轨。@jimbob 给了你一些(而且这个列表并不详尽)。计算机安全的艺术不是让系统在正常条件下正常工作;更重要的是确保系统在异常情况下不会太不正常地工作

提供身份验证流程的通用“要点”的有趣之处在于,除非您真的搞砸了流程,否则您可能不会发现严重的问题,因为没有足够的细节来说明一种或另一种方式。通常情况下,其实施存在缺陷。

由于您没有指定要保护的内容,这使情况变得更加复杂。只传递一个用户名并登录是非常安全的*——在适当的条件下。您需要问自己的问题是您要保护谁或什么,以及您的身份验证流程是否提供了保护措施,以防止那些坏人向您投掷的任何东西。

您提到密码...您如何验证密码?

会话令牌...您如何生成它们,如何将它们存储在服务器上,如何将它们存储在客户端,如何在“任何操作”上验证令牌?

更多问题等...

这就是为什么建议您不要自己建造。您没有考虑到每个角度的可能性非常好,而知名组件的开发人员可能会考虑。例如,说生成会话令牌“只是一个实现细节”并不是完全不正确的,但它是一个严肃的细节,如果你把它搞砸了,它会让你大吃一惊。

所以我对你的问题的回答是:是的,这是不安全的,因为没有足够的细节来说明一种或另一种方式。

*好吧,也许不是,但你明白了。