Codeigniter CSRF - 它如何工作

25

最近我发现了关于CSRF攻击的内容,很高兴的是Codeigniter v 2.0.0已经增加了CSRF保护功能。

我启用了这个功能并发现在表单中会添加一个带有令牌的隐藏输入框,我猜测它也会将令牌存储在会话中。在进行POST请求时,CI会自动比较令牌还是我需要手动执行该操作呢?

4个回答

40

当使用form_open()函数时,CSRF令牌会作为隐藏的输入添加到表单中。

由Security类创建一个带有CSRF令牌值的cookie,并在每个请求中根据需要重新生成。

如果存在$_POST数据,则Input类会自动验证cookie。如果发布的令牌与cookie的值不匹配,CI将显示错误并无法处理$_POST数据。

基本上,这是全自动的 - 您只需在您的$config['csrf_protection']中启用它,并为您的表单使用form_open()函数即可。

我发现了一篇很好的文章,非常好地解释了它:https://beheist.com/blog/csrf-protection-in-codeigniter-2-0-a-closer-look.html


2
谢谢您的澄清!我很高兴选择CI作为我的框架 :) - CyberJunkie
1
谢谢,但链接已失效。 - 4Jean
完美而有用的答案。通过正确的指导节省了很多时间。谢谢您先生! - arefindev
@WesleyMurch 我想知道你是否指的是保存在客户端的 cookie。用户无法操纵这些 cookie 以使其对他们有利吗? - Daniyal Nasir

3

2

启用csrf保护后,安全类会自动检查此令牌(它将POST令牌与COOKIE令牌进行比较)。


0

对于 codeigniter4,您可以通过更改您的app/Config/Filters.php并全局启用csrf过滤器来启用CSRF保护:

public $globals = [
        'before' => [
                //'honeypot'
                'csrf'
        ]
];

在这里更改名称 app/Config/App.php

/*
    |--------------------------------------------------------------------------
    | Cross Site Request Forgery
    |--------------------------------------------------------------------------
    | Enables a CSRF cookie token to be set. When set to TRUE, token will be
    | checked on a submitted form. If you are accepting user data, it is strongly
    | recommended CSRF protection be enabled.
    |
    | CSRFTokenName   = The token name
    | CSRFHeaderName  = The header name
    | CSRFCookieName  = The cookie name
    | CSRFExpire      = The number in seconds the token should expire.
    | CSRFRegenerate  = Regenerate token on every submission
    | CSRFRedirect    = Redirect to previous page with error on failure
    */
    //public $CSRFTokenName  = 'csrf_test_name';
    public $CSRFTokenName  = 'form_csrf';
    public $CSRFHeaderName = 'X-CSRF-TOKEN';
    public $CSRFCookieName = 'csrf_cookie_name';
    public $CSRFExpire     = 7200;
    public $CSRFRegenerate = true;
    public $CSRFRedirect   = true;

如果您使用表单助手,则form_open()将自动在您的表单中插入一个隐藏的csrf字段。如果没有,则可以使用始终可用的csrf_token()csrf_hash()函数。
helper('form');//::::Load form helper

echo form_open('/u/sign-up', ['csrf_id' => 'my-id']);

将返回:

<form action="http://example.com/index.php/u/sign-up" method="post" accept-charset="utf-8">
    <input type="hidden" id="my-id" name="form_csrf" value="964ede6e0ae8a680f7b8eab69136717d" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接