【发布时间】:2018-09-10 20:51:28
【问题描述】:
安全。今天,如果没有适当的安全性编程到互联网上,任何应用程序都无法在互联网上生存 - 无论是开发人员使用的框架,还是开发人员自己。我目前正在开发一个 RESTful API 以使用 Bearer 令牌身份验证,但一直在阅读有关 XSS 和 CSRF 攻击的信息。
问题 1) 根据我的阅读,我发现使用基于令牌的身份验证的 RESTful API 的应用程序容易受到 XSS 的攻击,不是如果令牌是 CSRF存储在浏览器的 localStorage/sessionStorage 中,而不是 cookie 中。这是因为,要使 CSRF 工作,应用程序必须使用 cookie。我说的对吗?
但是现在令牌存储在 localStorage/sessionStorage 中,应用程序变得容易受到 XSS 攻击。如果应用程序的任何部分没有清理输入(例如,Angular 输入由框架清理,但我使用的某个第 3 方库可能默认不清理输入),那么攻击者可以注入恶意代码窃取其他用户的令牌,然后通过模拟他们发出经过身份验证的请求。
问题 2) 有一种方法可以在使用 RESTful API 的应用程序中防止这两种攻击。我遇到了this post。那篇文章的要点是,在用户登录并请求不记名令牌时,让服务器也返回一个httpOnly cookie,例如CSRFProtectionCookie。我相信本文中的解决方案非常强大,并提供了强大的保护。再说一遍,我说的对吗?你有什么看法?
我的应用程序和我上面帖子中提到的方法的版本
上面帖子中提到的方法要求我将CSRFProtectionCookie 持久化到某种数据库中。我不想那样做。我不希望每次向 API 发出经过身份验证的请求时都会访问数据库。相反,我能做的是:
登录
- 用户使用用户名和密码向令牌端点发送 POST 请求
- 授权服务器验证用户凭据并开始使用某些声明构建 JWT。
- 作为 JWT 构建的一部分,它还会生成一个随机字符串,对其进行散列,然后将其作为
csrf声明添加到 JWT。 - 此外,接下来服务器设置一个名为
XSRF-TOKEN的httpOnlycookie,其值是相同的随机字符串,但这次加密。 - 将响应返回给浏览器。浏览器获取不记名令牌作为响应正文,并设置了
XSRF-TOKENcookie。
经过身份验证的请求
应用程序通过将 JWT 不记名令牌添加为
Authorization标头来调用经过身份验证的端点。浏览器会自动发送 cookie。服务器解密 cookie 以获取纯文本。然后服务器使用 JWT 中的哈希验证这个纯文本。
如果匹配,则继续请求。否则,返回未经授权的响应。
我认为这可以同时防止 CSRF 和 XSS。因为需要令牌和 cookie (httpOnly) 才能发出经过身份验证的请求。
问题是的,这消除了将任何内容持久化到数据库的需要(或者是这样吗?我错过了一些漏洞吗?)。但是在每个用户请求上解密和验证哈希的开销是多少?它是否比数据库 I/O 开销更大?此外,欢迎对这种方法或其他方法提出任何其他建议!
谢谢:)
【问题讨论】:
-
你不必坚持任何东西来有效地防止 csrf,请参阅双重发布。 XSS 不会被任何框架完全缓解,而且你似乎并不了解 XSS,所以要小心那个。您的方法不提供保护。施奈尔定律也适用。 :)
-
施奈尔定律让人觉得自己像个傻瓜 xD 但是是的,我会马上阅读关于双重发布的内容!另外,您能否解释一下这个版本如何/为什么不提供保护?