2

我四处搜寻,但找不到任何关于此的信息。我是唯一一个体验过 CodeIgniter 中的 CSRF 保护不适用于页面缓存的人吗?

我有什么:

将通过此行缓存的网页:

$this->output->cache( 120 );

在该页面上的 Javascript 中,我有一个 Ajax 调用,其中数据也包含 CSRF 令牌。禁用缓存或禁用 CSRF 保护时一切正常。

有人知道解决方法或其他东西,以便我可以启用缓存和 CSRF 保护吗?

谢谢!

4

1 回答 1

1

我有点惊讶form_open()它不能为你处理这个问题,就像基准函数的输出没有被缓存一样。

以下是两种可能的解决方法。

使用缓存驱动程序 (!= output->cache())

您可以使用缓存驱动程序的键值缓存来保存页面的渲染部分,而不是使用缓存完全呈现的页面的输出类缓存。

如果包含这个有问题的 CSRF 令牌的表单很复杂并且包含来自外部数据源的大量动态内容,请缓存这些数据库结果(使用缓存驱动程序或通过启用数据库结果缓存)并将缓存的值提供给动态表单。

手册中有关基于文件的缓存的警告:

与来自输出类的缓存不同,基于驱动程序文件的缓存允许缓存视图文件的片段。谨慎使用它,并确保对您的应用程序进行基准测试,因为磁盘 I/O 可能会抵消缓存带来的积极收益。

当然,如果您可以访问 memcached 或 APC,请改用它。

禁用该页面和配置文件的输出缓存。

拦截输出缓存(完全渲染的页面)并替换 CSRF 令牌值

我遇到了一个关于使用 CSRF 令牌缓存表单的有趣解决方案(在 Symfony 中)。套用原作者的话:

  1. 在设置缓存响应之前,查找并替换 CSRF 令牌。
  2. 将标记的位置与响应一起存储(因此它也会被缓存)。
  3. 在从缓存返回响应之前,注入新的 CSRF 令牌。

在 CodeIgniter 中,拦截缓存似乎需要使用hook-point ,但在您pre_system情况下,您可以使用cache_override. 看看这篇关于 CodeIgniter 实现 CRSF 令牌的方式的优秀文章以获得灵感。不过,我认为实施起来并不容易。

不要缓存该页面,也不要担心它

这显然是最简单的解决方案。测试一下。根据您的页面复杂性,不缓存该页面子集的负面性能影响可能远远超过实现上述两种解决方案中的任何一种的痛苦。(由于我们不知道您的视图或控制器是什么样的,因此在您的情况下这是否是可接受的解决方案并不是很明显)。如果它是 SPA 中的一个独立登录表单,您可能会侥幸逃脱。

于 2013-02-28T16:17:31.553 回答