使用服务器端缓存时的 CSRF 保护



>情况

examp.le有一个站点需要花费大量 CPU/RAM 来生成,还有一个更精简的examp.le/backend,它将执行各种任务来读取、写入和提供用户特定的数据,用于经过身份验证的请求。通过利用examp.le站点上的服务器端缓存,可以节省大量资源,而不是examp.le/backend,并且在页面到达客户端后从后端异步获取所有用户特定的数据。(尽管需要额外的请求,但总加载时间甚至可能更短。

威胁模型

CSRF 攻击。假设(也许是愚蠢的(examp.le可以可靠地防止XSS代码注入,我们仍然需要考虑恶意站点exploit.me上的脚本,这些脚本会导致受害者浏览器自动包含其授权cookie对examp.le/backend运行请求,并导致服务器代表用户执行某种数据更改。

解决方案/问题

据我了解,常用的对策是在生成的exampl.le页面中包含另一个令牌。服务器可以验证此令牌是否已链接到当前用户的会话,并且仅接受可以提供该令牌的请求。但是我认为,如果我们在每个响应中烘焙一个随机令牌,缓存将无法很好地工作examp.le..?

那么...

我看到了两种可能的解决方案:一种是某种"混合缓存",其中对examp.le的每个响应仍然是以编程方式生成的,但该程序只是将小的动态部分合并到一些缓存的输出中。不适用于在服务器堆栈的较高层上运行的缓存系统,更不用说 CDN,但仍然可能有其优点。我不知道是否有标准的方法或库来做到这一点,或者更具体地说,是否有 wordpress 的解决方案(这恰好是我的情况的罪魁祸首(。

另一个(首选(解决方案是直接从examp.le/backend获取初始的反CSRF令牌。但我不太清楚我对此的含义的理解。如果exploit.me上的脚本可以以某种方式获得该令牌,那么整个机制将毫无意义。我的理解是,如果我们把可利用的浏览器错误和安全漏洞排除在外,只考虑来自访问exploit.me的非晦涩浏览器的请求,那么绝对可以信任HTTP_ORIGIN标头是防篡改的。这是对的吗?但这就引出了一个问题:在这种情况下,我们是否可以通过只检查身份验证 cookie 和源标头而不来回抛出令牌来获得基本相同的安全性?

如果这个问题感觉有点到处都是,我很抱歉,但我部分仍在了解整个画面的过程中;-(

首先:跨站点脚本(XSS(和跨站点请求伪造(CSRF(是两种不同的攻击类别。我假设,你的意思只是解决CSRF问题。

其次:了解CSRF是什么是至关重要的。请考虑以下操作。

  1. 用于exampl.le/backend更改某种关键数据的 POST 请求
  2. exampl.le/backend的请求受身份验证机制保护,这些机制会生成有效的会话 Cookie。
  3. 我想攻击你。我通过向您发送指向我在cats.combest_cats_evr伪造的页面的链接来做到这一点。
  4. 如果您在一个浏览器选项卡中登录以exampl.le,并在另一个浏览器中打开cats.combest_cats_evr,则将执行代码。
  5. 站点上的代码cats.combest_cats_evr将向exampl.le/backend发送 POST 请求。饼干将被附加,因为没有理由不应该。您将在不知情的情况下对exampl.le/backend执行更改。

那么,话虽如此,我们如何防止此类攻击?

CSRF案例在社区中非常熟悉,我自己写下所有内容是没有意义的。请查看OWASP CSRF预防备忘单,因为它是您可以在本主题中找到的最佳页面之一。

是的,在这种情况下检查原点会有所帮助。但是检查原点将无济于事,如果我在exampl.le/somewhere_else中发现XSS漏洞并将其用于对付您。

同样有帮助的是不使用 POST 请求(因为它们可以在没有源检查的情况下进行操作(,而是在 CORS 应该提供帮助的地方使用 PUT......但这很快就会被证明是开发团队无法处理的火箭科学,并且坚持使用旧的反CSRF代币(每个框架默认支持(应该会有所帮助。

相关内容

  • 没有找到相关文章

最新更新