CodeIgniter CSRF保护和页面缓存

时间:2013-02-27 19:31:45

标签: codeigniter caching csrf

我已经四处寻找但却无法找到任何相关信息。我是唯一一个在CodeIgniter中体验过CSRF保护的人不能使用页面缓存吗?

我有什么:

将通过此行缓存的网页:

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

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

是否有人知道某种解决方法或某些内容,以便我可以启用缓存和CSRF保护?

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

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

您可以使用caching driver's key-value cache来保存页面的部分,而不是使用缓存完全呈现的页面的输出类缓存。

如果包含此有问题的CSRF令牌的表单很复杂并且包含来自外部数据源的大量动态内容,请缓存这些数据库结果(使用缓存驱动程序或启用database result caching)并提供缓存的值变成一种动态的形式。

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

  

与Output Class中的缓存不同,基于驱动程序文件的缓存   允许缓存视图文件。小心使用,并且   确保对您的应用程序进行基准测试,因为一个点可以来到哪里   磁盘I / O将通过缓存否定正增益。

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

禁用该页面和个人资料的输出缓存。

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

我在Caching forms with CSRF tokens(在Symfony中)遇到了一个有趣的解决方案。解释原作者:

  1. 在设置缓存响应之前,请查找并替换CSRF令牌。
  2. 使用响应存储令牌的位置(因此它也会被缓存)。
  3. 在从缓存中返回响应之前注入新的CSRF令牌。
  4. 在CodeIgniter中,截取seems to require的缓存the pre_system hook-point使用,但在您的情况下,您可以使用cache_override。看看at this excellent article在CodeIgniter实现CRSF令牌的方式上的灵感。不过,我认为实施起来并不容易。

    不要缓存该页面而不用担心

    这显然是最简单的解决方案。测试一下。根据您的页面复杂性,不缓存该页面子集的负面性能影响可能超过实现上述两种解决方案中的任何一种的痛苦。 (因为我们不知道你的观点或控制器是什么样的,在你的情况下这是否是一个可接受的解决方案并不是很明显)。如果它是isolated login form in an SPA,你可以探索它。