Using CSRF Protection in the Login Form
Warning: You are browsing the documentation for Symfony 3.x, which is no longer maintained.
Read the updated version of this page for Symfony 7.0 (the current stable version).
When using a login form, you should make sure that you are protected against CSRF (Cross-site request forgery). The Security component already has built-in support for CSRF. In this article you'll learn how you can use it in your login form.
Note
Login CSRF attacks are a bit less well-known. See Forging Login Requests if you're curious about more details.
Configuring CSRF Protection
First, make sure that the CSRF protection is enabled in the main configuration file:
1 2 3 4
# app/config/config.yml
framework:
# ...
csrf_protection: ~
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config>
<framework:csrf-protection enabled="true"/>
</framework:config>
</container>
1 2 3 4
// app/config/config.php
$container->loadFromExtension('framework', [
'csrf_protection' => null,
]);
Then, the security component needs a CSRF token provider. You can set this to use the default provider available in the security component:
1 2 3 4 5 6 7 8 9 10
# app/config/security.yml
security:
# ...
firewalls:
secured_area:
# ...
form_login:
# ...
csrf_token_generator: security.csrf.token_manager
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<!-- app/config/security.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
https://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<!-- ... -->
<firewall name="secured_area">
<!-- ... -->
<form-login csrf-token-generator="security.csrf.token_manager"/>
</firewall>
</config>
</srv:container>
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// app/config/security.php
$container->loadFromExtension('security', [
// ...
'firewalls' => [
'secured_area' => [
// ...
'form_login' => [
// ...
'csrf_token_generator' => 'security.csrf.token_manager',
],
],
],
]);
The Security component can be configured further, but this is all information it needs to be able to use CSRF in the login form.
Tip
If you're using a Guard Authenticator, you'll need to validate the CSRF token manually inside of that class. See How to Create a Custom Authentication System with Guard for details.
Rendering the CSRF field
Now that Security component will check for the CSRF token, you have to add
a hidden field to the login form containing the CSRF token. By default,
this field is named _csrf_token
. That hidden field must contain the CSRF
token, which can be generated by using the csrf_token()
function. That
function requires a token ID, which must be set to authenticate
when
using the login form:
1 2 3 4 5 6 7 8 9 10 11 12
{# src/AppBundle/Resources/views/Security/login.html.twig #}
{# ... #}
<form action="{{ path('login') }}" method="post">
{# ... the login fields #}
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
<button type="submit">login</button>
</form>
After this, you have protected your login form against CSRF attacks.
Tip
You can change the name of the field by setting csrf_parameter
and change
the token ID by setting csrf_token_id
in your configuration:
1 2 3 4 5 6 7 8 9 10 11
# app/config/security.yml
security:
# ...
firewalls:
secured_area:
# ...
form_login:
# ...
csrf_parameter: _csrf_security_token
csrf_token_id: a_private_string
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<!-- app/config/security.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
https://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<!-- ... -->
<firewall name="secured_area">
<!-- ... -->
<form-login csrf-parameter="_csrf_security_token"
csrf-token-id="a_private_string"
/>
</firewall>
</config>
</srv:container>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// app/config/security.php
$container->loadFromExtension('security', [
// ...
'firewalls' => [
'secured_area' => [
// ...
'form_login' => [
// ...
'csrf_parameter' => '_csrf_security_token',
'csrf_token_id' => 'a_private_string',
],
],
],
]);