使用 JSON Web 令牌进行 CSRF 保护

问题描述 投票:0回答:2

我读到,使用 JWT 时,无需防范 CSRF 攻击,例如:“由于您不依赖 cookie,因此无需防范跨站请求”。

但是,我不明白的是:如果我将令牌存储在

localStorage
中(正如我在同一网站的教程上建议的那样),什么可以防止攻击者通过读取我的localStorage
来伪造恶意请求我的饼干?

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

local-storage csrf jwt auth0
2个回答
168
投票
严格来说,是的,存储在本地/会话存储(我将其称为 HTML5 存储)中的任何内容都可能在跨站点脚本 (XSS) 攻击中被窃取。请参阅

本文

但是,有很多移动部件需要考虑。

首先,HTML5 存储和 cookie 在 JavaScript 访问方面的范围存在细微差别。

HTML5 存储是:

    分为HTTP和HTTPS。
  • http://example.com
     HTML5 存储中存储的项目无法通过在 
    https://example.com
     上运行的 JavaScript 访问。
  • 在子域之间划分。存储在
  • http://example.com
     HTML5 存储中的项目无法通过在 
    http://sub.example.com
     上运行的 JavaScript 访问(不过,您可以使用一些 
    技巧 来解决这个问题)。
饼干更松软:

    具有域
  • example.com
     的 cookie 将同时发送至 
    http://example.com
    https://example.com
     
    除非它具有属性 secure
    ,在这种情况下,它将仅发送至 
    https
  • 未使用显式域发送的 cookie 将仅发送回发送它的确切域。如果域明确定义为
  • example.com
    ,那么它将被发送到 
    example.com
    sub.example.com
    。 (这是 cookie“规范”中最令人困惑的部分,不幸的是,请参阅
    这篇文章)。
  • 如果 cookie 运行在具有匹配域的页面上(并且遵守
  • secure
     cookie 标志),则 JavaScript 可以读取 cookie 
    除非 cookie 具有 httpOnly
     属性,在这种情况下 JavaScript 将无法读取读一下。
其次,由于 cookie 带有域标记,因此当向服务器发出请求时,浏览器将发送具有匹配域的唯一 cookie,

无论发起请求的页面的域是什么

最后一部分是CSRF攻击是如何完成的(同源策略的帮助有限)。 CSRF 上的 OWASP 页面是了解此类攻击如何运作的良好资源。

将身份验证令牌存储在本地存储中并手动将其添加到每个请求中可以防止 CSRF 的原因是关键字:手动。由于浏览器不会自动发送该身份验证令牌,因此如果我访问 evil.example

并且它设法发送

POST http://example.com/delete-my-account

,它将无法发送我的身份验证令牌,因此该请求将被忽略。
考虑到上述情况,是使用 cookie 还是 HTML5 存储就变成了一系列的权衡:

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

(-)
    在 XSS 攻击中被盗的风险。
  • (+)
  • 提供 CSRF 保护。
  • (-)
  • 必须手动修改发送到服务器的每个请求,从而限制您只能使用 SPA(例如 AngularJS)Web 应用程序。
  • 另一方面,如果您将身份验证令牌存储在标记为 
  • httpOnly

 
secure 的 cookie 中,则:

(+)
    authn 令牌无法被 XSS 窃取。
  • (-)
  • 您必须自己提供 CSRF 保护。在某些框架中实现 CSRF 保护比其他框架更容易。
  • 哪个选项更好取决于您的需求。

您的身份验证令牌是否保护与金钱有关的任何内容?您可能需要 cookie

httpOnly
  • secure
     选项。
    实施 CSRF 保护所需的努力是否不值得其保护的资产?那么 HTML5 存储可能是正确的地方。
使用基于令牌的身份验证时,您必须手动将令牌与请求关联。与 cookie 相反,令牌不是由浏览器自动设置的,因此不易受到

6
投票
攻击。

虽然这种方法不会受到 
csrf

攻击,但它很容易受到

xss

 攻击。
最小的改进是使用 
session storage

而不是

local storage

,因为 
session storage
 数据在用户关闭选项卡/浏览器后被清除。

© www.soinside.com 2019 - 2024. All rights reserved.