Skip to content

Commit c03f7e9

Browse files
committed
Merge pull request #3327 from WouterJ/issue_3059
Documented CSRF protection in login forms
2 parents 2f89b3a + d1e6b4f commit c03f7e9

File tree

4 files changed

+172
-1
lines changed

4 files changed

+172
-1
lines changed

book/security.rst

+6-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ First, enable form login under your firewall:
319319
<config>
320320
<firewall name="secured_area" pattern="^/">
321321
<anonymous />
322-
<form-login login_path="login" check_path="login_check" />
322+
<form-login login-path="login" check-path="login_check" />
323323
</firewall>
324324
</config>
325325
</srv:container>
@@ -519,6 +519,11 @@ Finally, create the corresponding template:
519519
<button type="submit">login</button>
520520
</form>
521521

522+
.. caution::
523+
524+
This login form is currently not protected against CSRF attacks. Read
525+
:doc:`/cookbook/security/csrf_in_login_form` on how to protect your login form.
526+
522527
.. tip::
523528

524529
The ``error`` variable passed into the template is an instance of

cookbook/map.rst.inc

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
* :doc:`/cookbook/security/custom_provider`
134134
* :doc:`/cookbook/security/custom_authentication_provider`
135135
* :doc:`/cookbook/security/target_path`
136+
* :doc:`/cookbook/security/csrf_in_login_form`
136137

137138
* **Serializer**
138139

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
.. index::
2+
single: Security; CSRF in the Login Form
3+
4+
Using CSRF in the Login Form
5+
============================
6+
7+
When using a login form, you should make sure that you are protected against CSRF
8+
(`Cross-site request forgery`_). The Security component already has built-in support
9+
for CSRF. In this article you'll learn how you can use it in your login form.
10+
11+
Configuring CSRF
12+
----------------
13+
14+
At first, you have to configure the Security component so it can use CSRF protection.
15+
The Security component needs a CSRF provider. You can set this to use the default
16+
provider available in the Form component:
17+
18+
.. configuration-block::
19+
20+
.. code-block:: yaml
21+
22+
# app/config/security.yml
23+
security:
24+
firewalls:
25+
secured_area:
26+
# ...
27+
form_login:
28+
# ...
29+
csrf_provider: form.csrf_provider
30+
31+
.. code-block:: xml
32+
33+
<!-- app/config/config.xml -->
34+
<?xml version="1.0" encoding="UTF-8" ?>
35+
<srv:container xmlns="http://symfony.com/schema/dic/security"
36+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
37+
xmlns:srv="http://symfony.com/schema/dic/services"
38+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
39+
40+
<config>
41+
<firewall name="secured_area">
42+
<!-- ... -->
43+
44+
<form-login csrf-provider="form.csrf_provider" />
45+
</firewall>
46+
</config>
47+
</srv:container>
48+
49+
.. code-block:: php
50+
51+
// app/config/security.php
52+
$container->loadFromExtension('security', array(
53+
'firewalls' => array(
54+
'secured_area' => array(
55+
// ...
56+
'form_login' => array(
57+
// ...
58+
'csrf_provider' => 'form.csrf_provider',
59+
)
60+
)
61+
)
62+
));
63+
64+
The Security component can be configured further, but this is all information it needs
65+
to be able to use CSRF in the login form.
66+
67+
Rendering the CSRF field
68+
------------------------
69+
70+
Now the Security component checks for CSRF tokens, you have to add a *hidden* field
71+
to the login form containing the CSRF token. By default, this field is named as
72+
``_csrf_token``. That hidden field has to contain the CSRF token, which can be generated
73+
by using the ``csrf_token`` function. That function requires a token ID, which must
74+
be set to ``authenticate`` when using the login form:
75+
76+
.. configuration-block::
77+
78+
.. code-block:: html+twig
79+
80+
{# src/Acme/SecurityBundle/Resources/views/Security/login.html.twig #}
81+
82+
{# ... #}
83+
<form action="{{ path('login_check') }}" method="post">
84+
{# ... the login fields #}
85+
86+
<input type="hidden" name="_csrf_token"
87+
value="{{ csrf_token('authenticate') }}"
88+
>
89+
90+
<button type="submit">login</button>
91+
</form>
92+
93+
.. code-block:: html+php
94+
95+
<!-- src/Acme/SecurityBundle/Resources/views/Security/login.html.php -->
96+
97+
<!-- ... -->
98+
<form action="<?php echo $view['router']->generate('login_check') ?>" method="post">
99+
<!-- ... the login fields -->
100+
101+
<input type="hidden" name="_csrf_token"
102+
value="<?php echo $view['form']->csrfToken('authenticate') ?>"
103+
>
104+
105+
<button type="submit">login</button>
106+
</form>
107+
108+
After this, you have protected your login form against CSRF attacks.
109+
110+
.. tip::
111+
112+
You can change the name of the field by setting ``csrf_parameter`` and change
113+
the token ID by setting ``intention`` in your configuration:
114+
115+
.. configuration-block::
116+
117+
.. code-block:: yaml
118+
119+
# app/config/security.yml
120+
security:
121+
firewalls:
122+
secured_area:
123+
# ...
124+
form_login:
125+
# ...
126+
csrf_parameter: _csrf_security_token
127+
intention: a_private_string
128+
129+
.. code-block:: xml
130+
131+
<!-- app/config/config.xml -->
132+
<?xml version="1.0" encoding="UTF-8" ?>
133+
<srv:container xmlns="http://symfony.com/schema/dic/security"
134+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
135+
xmlns:srv="http://symfony.com/schema/dic/services"
136+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
137+
138+
<config>
139+
<firewall name="secured_area">
140+
<!-- ... -->
141+
142+
<form-login csrf-parameter="_csrf_security_token"
143+
intention="a_private_string" />
144+
</firewall>
145+
</config>
146+
</srv:container>
147+
148+
.. code-block:: php
149+
150+
// app/config/security.php
151+
$container->loadFromExtension('security', array(
152+
'firewalls' => array(
153+
'secured_area' => array(
154+
// ...
155+
'form_login' => array(
156+
// ...
157+
'csrf_parameter' => '_csrf_security_token',
158+
'intention' => 'a_private_string',
159+
)
160+
)
161+
)
162+
));
163+
164+
.. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery

cookbook/security/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ Security
1515
custom_provider
1616
custom_authentication_provider
1717
target_path
18+
csrf_in_login_form

0 commit comments

Comments
 (0)