Documentação do Symfony - versão 3.1
Renderizada do repositório symfony-docs-pt-BR no Github

Usando Proteção CSRF no Formulário de Login

Ao usar um formulário de login, você deve certificar-se que ele está protegido contra CSRF (Cross-site request forgery). O componente de Segurança já possui suporte integrado para CSRF. Neste artigo você vai aprender como pode usá-lo em seu formulário de login.

Note

Ataques CSRF de login são um pouco menos conhecidos. Veja Forjar Solicitações de Login se você está curioso para saber mais detalhes.

Configurando a Proteção CSRF

Primeiro, configure o componente de Segurança para que ele possa usar a proteção CSRF. O componente de Segurança precisa de um provedor de token CSRF. Você pode usar o provider padrão disponível no componente de Formulário:

  • YAML
    1
    2
    3
    4
    5
    6
    7
    8
    # app/config/security.yml
    security:
        firewalls:
            secured_area:
                # ...
                form_login:
                    # ...
                    csrf_provider: form.csrf_provider
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    <!-- app/config/config.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <srv:container xmlns="http://symfony.com/schema/dic/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:srv="http://symfony.com/schema/dic/services"
        xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    
        <config>
            <firewall name="secured_area">
                <!-- ... -->
    
                <form-login csrf-provider="form.csrf_provider" />
            </firewall>
        </config>
    </srv:container>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    // app/config/security.php
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'secured_area' => array(
                // ...
                'form_login' => array(
                    // ...
                    'csrf_provider' => 'form.csrf_provider',
                )
            )
        )
    ));
    

O componente de Segurança pode ser configurado ainda, mas essa é toda a informação que ele precisa para utilizar CSRF no formulário de login.

Renderizando o campo CSRF

Agora que o componente de Segurança irá verificar o token CSRF, você tem que adicionar um campo hidden no formulário de login que contém o token CSRF. Por padrão, esse campo é chamado _csrf_token. Esse campo oculto deve conter o token CSRF, que pode ser gerado usando a função csrf_token. Essa função requer um ID de token, que deve ser definido como authenticate ao usar o formulário de login:

  • Twig
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    {# src/Acme/SecurityBundle/Resources/views/Security/login.html.twig #}
    
    {# ... #}
    <form action="{{ path('login_check') }}" method="post">
        {# ... the login fields #}
    
        <input type="hidden" name="_csrf_token"
            value="{{ csrf_token('authenticate') }}"
        >
    
        <button type="submit">login</button>
    </form>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    <!-- src/Acme/SecurityBundle/Resources/views/Security/login.html.php -->
    
    <!-- ... -->
    <form action="<?php echo $view['router']->generate('login_check') ?>" method="post">
        <!-- ... the login fields -->
    
        <input type="hidden" name="_csrf_token"
            value="<?php echo $view['form']->csrfToken('authenticate') ?>"
        >
    
        <button type="submit">login</button>
    </form>
    

Após isso, você tem seu formulário de login protegido contra ataques CSRF.

Tip

Você pode alterar o nome do campo definindo csrf_parameter e alterando o ID de token setando intention em sua configuração:

  • YAML
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # app/config/security.yml
    security:
        firewalls:
            secured_area:
                # ...
                form_login:
                    # ...
                    csrf_parameter: _csrf_security_token
                    intention: a_private_string
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    <!-- app/config/config.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <srv:container xmlns="http://symfony.com/schema/dic/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:srv="http://symfony.com/schema/dic/services"
        xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    
        <config>
            <firewall name="secured_area">
                <!-- ... -->
    
                <form-login csrf-parameter="_csrf_security_token"
                    intention="a_private_string" />
            </firewall>
        </config>
    </srv:container>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    // app/config/security.php
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'secured_area' => array(
                // ...
                'form_login' => array(
                    // ...
                    'csrf_parameter' => '_csrf_security_token',
                    'intention'      => 'a_private_string',
                )
            )
        )
    ));