如何去实现CSRF 保护

3.4 版本
维护中的版本

CSRF–Cross-site request forgery,跨站伪造请求 是恶意攻击者试图让你的合法用户在不知不觉中提交他们本不想提交的数据的一种方法。幸运的是,CSRF攻击可以通过在你的表单中使用CSRF 记号来阻止。

默认情况下,Symfony自动为你嵌入一个合法的CSRF令牌。这就意味着你不需要做任何事情就可以得到CSRF保护。

CSRF保护是通过在你的表单中添加一个隐藏字段,默认的名叫_token。它包含一个值,这个值只有你和你的用户知道。这确保了是用户而不是其它实体在提交数据。Symfony自动校验该token是否存在以及其准确性。

_token 字段是一个隐藏字段并且会自动的渲染,只要你在你的模板中包含了form_end()函数。它确保了没有被渲染过的字段全部渲染出来。

由于token被存储在session中,当你表单开始渲染CSRF保护就会自动启动一个session。

CSRF令牌可以按照表单来个性化,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Symfony\Component\OptionsResolver\OptionsResolver;
 
class TaskType extends AbstractType
{
    // ...
 
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'      => 'AppBundle\Entity\Task',
            'csrf_protection' => true,
            'csrf_field_name' => '_token',
            // a unique key to help generate the secret token
            'csrf_token_id'   => 'task_item',
        ));
    }
 
    // ...
}

要关闭CSRF保护,设置csrf_protection选项为false。如果想了解更多信息,请参见form configuration reference

csrf_token_id选项是可选的,但为不同的表单生成不同的令牌极大的加强了安全性。

CSRF令牌对于每个用户都是不同的。如果你试图缓存页面,你就需要谨慎了,因为form使用了这种保护。想了解更多信息请查看cookbook--对包含了CSRF防护的表单页面进行缓存.

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)