使用JSON Web令牌进行CSRF保护

时间:2016-02-09 12:01:43

标签: local-storage csrf jwt auth0

我读到使用JWT时,没有必要防范CRSF攻击,例如:" since you are not relying on cookies, you don't need to protect against cross site requests"。

但是,我不明白:如果我将令牌存储在localStorage中(因为我被告知on a tutorial of the same website),是什么阻止攻击者通过读取我的localStorage而不是我的cookie来伪造恶意请求?

由于它是在服务器端生成的,因此我不知道如何将令牌用于客户端请求而不将其存储在客户端的某个位置。

2 个答案:

答案 0 :(得分:89)

严格来说,是的,存储在本地/会话存储中的任何内容(我称之为HTML5存储)都可能在跨站点脚本(XSS)攻击中被盗。请参阅this article

然而,有许多可动部件需要考虑。

首先,HTML5存储和Cookie在JavaScript访问方面的作用方式存在细微差别。

HTML5存储是:

  • 分为http和https。 http://example.com上运行的JavaScript无法访问存储在https://example.com HTML5存储空间中的项目。
  • 在子域之间划分。 http://example.com上运行的JavaScript无法访问存储在http://sub.example.com HTML5存储空间中的项目(您可以执行一些tricks来解决此问题)。

饼干更松散了:

  • 包含域example.com的Cookie将同时转到http://example.comhttps://example.com ,除非它具有属性secure,在这种情况下它只会发送到https
  • 未使用显式域发送的Cookie只会发送回发送它的确切域。如果域明确定义为example.com,则会将其发送给example.comsub.example.com。 (这是cookie中最令人困惑的部分" spec",不幸的是,请参阅this article)。
  • 如果cookie在具有匹配域的页面上运行(并且尊重secure cookie标志),则可以通过JavaScript读取cookie,除非该cookie具有httpOnly属性,在这种情况下,JavaScript将无法读取它。

其次,由于Cookie是使用域标记的,因此当向服务器发出请求时,浏览器将发送具有匹配域的所有cookie,而不管源自哪个域的域。请求

最后一部分是如何完成CSRF攻击(同源政策只能帮助这么多)。 OWASP page on CSRF是了解这类攻击如何运作的良好资源。

将身份验证令牌存储在本地存储中并手动将其添加到每个请求的原因可以防止CSRF成为关键字:manual。由于浏览器没有自动发送该身份验证令牌,如果我访问evil.com并且它设法发送POST http://example.com/delete-my-account,则无法发送我的身份验证令牌,因此会忽略该请求。

考虑到上述因素,无论是使用cookie还是HTML5存储都会成为一系列权衡因素:

将身份验证令牌存储在HTML5存储中意味着:

  • (-)在XSS攻击中被盗的风险。
  • (+)提供CSRF保护。
  • (-)必须手动修改发往服务器的每个请求,限制您使用SPA(例如AngularJs)Web应用程序。

另一方面,如果您将authn令牌存储在标记为httpOnly secure的Cookie中,则:

  • (+) XSS无法盗取authn令牌。
  • (-)您必须自己提供CSRF保护。在某些框架中实施CSRF保护比其他框架更容易。

哪种选择更好取决于您的需求。

  • 你的authn令牌是否保护与钱有关的任何事情?您可能需要Cookie httpOnly secure选项。
  • 实施CSRF保护所需的工作量是否值得保护?那么HTML5存储可能是正确的位置。

答案 1 :(得分:1)

使用基于令牌的身份验证时,必须手动将令牌与请求关联。与Cookie相反,浏览器不会自动设置令牌,因此不易受到csrf攻击。

尽管这种方法可以防止csrf攻击,但很容易受到xss攻击。

最省力的改进是使用session storage而不是local storage,因为session storage数据在用户关闭标签/浏览器后便被清除。