diff --git a/book/security.rst b/book/security.rst index 9977e7754cc..35d27275ba8 100644 --- a/book/security.rst +++ b/book/security.rst @@ -319,7 +319,7 @@ First, enable form login under your firewall: - + @@ -519,6 +519,11 @@ Finally, create the corresponding template: +.. caution:: + + This login form is currently not protected against CSRF attacks. Read + :doc:`/cookbook/security/csrf_in_login_form` on how to protect your login form. + .. tip:: The ``error`` variable passed into the template is an instance of diff --git a/book/validation.rst b/book/validation.rst index 6941d357465..ac4bacfdbd3 100644 --- a/book/validation.rst +++ b/book/validation.rst @@ -113,8 +113,9 @@ Next, to actually validate an ``Author`` object, use the ``validate`` method on the ``validator`` service (class :class:`Symfony\\Component\\Validator\\Validator`). The job of the ``validator`` is easy: to read the constraints (i.e. rules) of a class and verify whether or not the data on the object satisfies those -constraints. If validation fails, an array of errors is returned. Take this -simple example from inside a controller:: +constraints. If validation fails, a non-empty list of errors +(class :class:`Symfony\\Component\\Validator\\ConstraintViolationList`) is +returned. Take this simple example from inside a controller: // ... use Symfony\Component\HttpFoundation\Response; diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 9c8260fd929..924d8ece8cc 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -133,6 +133,7 @@ * :doc:`/cookbook/security/custom_provider` * :doc:`/cookbook/security/custom_authentication_provider` * :doc:`/cookbook/security/target_path` + * :doc:`/cookbook/security/csrf_in_login_form` * **Serializer** diff --git a/cookbook/security/csrf_in_login_form.rst b/cookbook/security/csrf_in_login_form.rst new file mode 100644 index 00000000000..74a4527af31 --- /dev/null +++ b/cookbook/security/csrf_in_login_form.rst @@ -0,0 +1,164 @@ +.. index:: + single: Security; CSRF in the Login Form + +Using CSRF in the Login Form +============================ + +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. + +Configuring CSRF +---------------- + +At first, you have to configure the Security component so it can use CSRF protection. +The Security component needs a CSRF provider. You can set this to use the default +provider available in the Form component: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + firewalls: + secured_area: + # ... + form_login: + # ... + csrf_provider: form.csrf_provider + + .. code-block:: xml + + + + + + + + + + + + + + + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + 'firewalls' => array( + 'secured_area' => array( + // ... + 'form_login' => array( + // ... + 'csrf_provider' => 'form.csrf_provider', + ) + ) + ) + )); + +The Security component can be configured further, but this is all information it needs +to be able to use CSRF in the login form. + +Rendering the CSRF field +------------------------ + +Now the Security component checks for CSRF tokens, you have to add a *hidden* field +to the login form containing the CSRF token. By default, this field is named as +``_csrf_token``. That hidden field has to 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: + +.. configuration-block:: + + .. code-block:: html+twig + + {# src/Acme/SecurityBundle/Resources/views/Security/login.html.twig #} + + {# ... #} +
+ {# ... the login fields #} + + + + +
+ + .. code-block:: html+php + + + + +
+ + + + + +
+ +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 ``intention`` in your configuration: + + .. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + firewalls: + secured_area: + # ... + form_login: + # ... + csrf_parameter: _csrf_security_token + intention: a_private_string + + .. code-block:: xml + + + + + + + + + + + + + + + .. code-block:: php + + // 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', + ) + ) + ) + )); + +.. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery diff --git a/cookbook/security/index.rst b/cookbook/security/index.rst index a8edbdc4317..c2623bcde64 100644 --- a/cookbook/security/index.rst +++ b/cookbook/security/index.rst @@ -15,3 +15,4 @@ Security custom_provider custom_authentication_provider target_path + csrf_in_login_form