Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Refactored the CSRF docs #8873

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions 7 _build/redirection_map
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
/cookbook/console/style /console/style
/cookbook/console/usage /console
/console/usage /console
/cookbook/controller/csrf_token_validation /controller/csrf_token_validation
/cookbook/controller/csrf_token_validation /security/csrf
/cookbook/controller/error_pages /controller/error_pages
/cookbook/controller/forwarding /controller/forwarding
/cookbook/controller/index /controller
Expand Down Expand Up @@ -221,7 +221,7 @@
/cookbook/security/acl /security/acl
/cookbook/security/acl_advanced /security/acl_advanced
/cookbook/security/api_key_authentication /security/api_key_authentication
/cookbook/security/csrf_in_login_form /security/csrf_in_login_form
/cookbook/security/csrf_in_login_form /security/csrf
/cookbook/security/custom_authentication_provider /security/custom_authentication_provider
/cookbook/security/custom_password_authenticator /security/custom_password_authenticator
/cookbook/security/custom_provider /security/custom_provider
Expand Down Expand Up @@ -361,7 +361,9 @@
/components/yaml/introduction /components/yaml
/components/yaml/index /components/yaml
/console/logging /console
/controller/csrf_token_validation /security/csrf
/deployment/tools /deployment
/form/csrf_protection /security/csrf
/install/bundles /setup/bundles
/email/gmail /email
/email/cloud /email
Expand All @@ -376,6 +378,7 @@
/frontend/assetic/yuicompressor /frontend/assetic
/reference/configuration/assetic /frontend/assetic
/security/target_path /security
/security/csrf_in_login_form /security/csrf
/service_container/third_party /service_container
/templating/templating_service /templates
/testing/simulating_authentication /testing/http_authentication
Expand Down
17 changes: 0 additions & 17 deletions 17 controller/csrf_token_validation.rst

This file was deleted.

74 changes: 0 additions & 74 deletions 74 form/csrf_protection.rst

This file was deleted.

2 changes: 1 addition & 1 deletion 2 forms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ That's it! Just three lines are needed to render the complete form:
Renders the end tag of the form and any fields that have not
yet been rendered, in case you rendered each field yourself. This is useful
for rendering hidden fields and taking advantage of the automatic
:doc:`CSRF Protection </form/csrf_protection>`.
:doc:`CSRF Protection </security/csrf>`.

.. seealso::

Expand Down
2 changes: 1 addition & 1 deletion 2 http_cache/form_csrf_caching.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ CSRF tokens are meant to be different for every user. This is why you
need to be cautious if you try to cache pages with forms including them.

For more information about how CSRF protection works in Symfony, please
check :doc:`CSRF Protection </form/csrf_protection>`.
check :doc:`CSRF Protection </security/csrf>`.

Why Caching Pages with a CSRF token is Problematic
--------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion 2 http_cache/varnish.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ If you know for sure that the backend never uses sessions or basic
authentication, have Varnish remove the corresponding header from requests to
prevent clients from bypassing the cache. In practice, you will need sessions
at least for some parts of the site, e.g. when using forms with
:doc:`CSRF Protection </form/csrf_protection>`. In this situation, make sure to
:doc:`CSRF Protection </security/csrf>`. In this situation, make sure to
:doc:`only start a session when actually needed </session/avoid_session_start>`
and clear the session when it is no longer needed. Alternatively, you can look
into :doc:`/http_cache/form_csrf_caching`.
Expand Down
4 changes: 2 additions & 2 deletions 4 reference/configuration/framework.rst
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ csrf_protection

.. seealso::

For more information about CSRF protection in forms, see :doc:`/form/csrf_protection`.
For more information about CSRF protection, see :doc:`/security/csrf`.

.. _reference-csrf_protection-enabled:

Expand All @@ -422,7 +422,7 @@ enabled
otherwise

This option can be used to disable CSRF protection on *all* forms. But you
can also :ref:`disable CSRF protection on individual forms <form-disable-csrf>`.
can also :ref:`disable CSRF protection on individual forms <form-csrf-customization>`.

If you're using forms, but want to avoid starting your session (e.g. using
forms in an API-only website), ``csrf_protection`` will need to be set to
Expand Down
2 changes: 1 addition & 1 deletion 2 security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ Authentication (Identifying/Logging in the User)
security/api_key_authentication
security/custom_authentication_provider
security/pre_authenticated
security/csrf_in_login_form
security/csrf
security/named_encoders
security/multiple_user_providers
security/multiple_guard_authenticators
Expand Down
173 changes: 113 additions & 60 deletions 173 security/csrf_in_login_form.rst → security/csrf.rst
Original file line number Diff line number Diff line change
@@ -1,59 +1,92 @@
.. index::
single: Security; CSRF Protection in the Login Form
single: CSRF; CSRF protection

Using CSRF Protection in the Login Form
=======================================
How to Implement CSRF Protection
================================

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.
CSRF - or `Cross-site request forgery`_ - is a method by which a malicious
user attempts to make your legitimate users unknowingly submit data that
they don't intend to submit.

.. note::
CSRF protection works by adding a hidden field to your form that contains a
value that only you and your user know. This ensures that the user - not some
other entity - is submitting the given data.

Login CSRF attacks are a bit less well-known. See `Forging Login Requests`_
if you're curious about more details.
Before enabling the CSRF protection, install the CSRF support in your project
(which in turn requires installing the Symfony Form component):

Configuring CSRF Protection
---------------------------
.. code-block:: terminal

First, make sure that the CSRF protection is enabled in the main configuration
file:
$ composer require security-csrf form

.. configuration-block::
CSRF Protection in Symfony Forms
--------------------------------

.. code-block:: yaml
Forms created with the Symfony Form component include CSRF tokens by default
and Symfony checks them automatically, so you don't have to anything to be
protected against CSRF attacks.

# config/packages/framework.yaml
framework:
# ...
csrf_protection: { enabled: true }
This automatic protection is enabled/disabled with the ``csrf_protection`` in
the ``config/packages/framework.yaml`` file. For more information, see the
:ref:`form configuration reference <reference-framework-form>`.

.. code-block:: xml
.. _form-csrf-customization:

<!-- config/packages/framework.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
http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony
http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
By default Symfony adds the CSRF token in a hidden field called ``_token``, but
this can be customized on a form-by-form basis::

<framework:config>
<framework:csrf-protection enabled="true" />
</framework:config>
</container>
// ...
use App\Entity\Task;
use Symfony\Component\OptionsResolver\OptionsResolver;

.. code-block:: php
class TaskType extends AbstractType
{
// ...

// config/packages/framework.php
$container->loadFromExtension('framework', array(
'csrf_protection' => null,
));
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Task::class,
// enable/disable CSRF protection for this form
'csrf_protection' => true,
// the name of the hidden HTML field that stores the token
'csrf_field_name' => '_token',
// an arbitrary string used to generate the value of the token
// using a different string for each form improves its security
'csrf_token_id' => 'task_item',
));
}

// ...
}

.. caution::

Since the token is stored in the session, a session is started automatically
as soon as you render a form with CSRF protection.

.. caution::

CSRF tokens are meant to be different for every user. Beware of that when
caching pages that include forms containing CSRF tokens. For more
information, see :doc:`/http_cache/form_csrf_caching`.

CSRF Protection in Login Forms
------------------------------

`Login CSRF attacks`_ can be prevented using the same technique of adding hidden
CSRF tokens into the login forms. The Security component already provides CSRF
protection, but you need to configure some options before using it.

.. tip::

If you're using a :doc:`Guard Authenticator </security/guard_authentication>`,
you'll need to validate the CSRF token manually inside of that class. See
:ref:`guard-csrf-protection` for details.

Then, the security component needs a CSRF token provider. You can set this to
use the default provider available in the security component:
First, configure the CSRF token provider used by the form login in your security
configuration. You can set this to use the default provider available in the
security component:

.. configuration-block::

Expand Down Expand Up @@ -107,26 +140,12 @@ use the default provider available in the security component:
),
));

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 :doc:`Guard Authenticator </security/guard_authentication>`,
you'll need to validate the CSRF token manually inside of that class. See
:ref:`guard-csrf-protection` for details.

.. _csrf-login-template:

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:
Then, use the ``csrf_token()`` function in the Twig template to generate a CSRF
token and store it as a hidden field of the form. By default, the HTML field
must be called ``_csrf_token`` and the string used to generate the value must
be ``authenticate``:

.. configuration-block::

Expand Down Expand Up @@ -223,5 +242,39 @@ After this, you have protected your login form against CSRF attacks.
),
));

.. _`Cross-site request forgery`: https://en.wikipedia.org/wiki/Cross-site_request_forgery
.. _`Forging Login Requests`: https://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests
CSRF Protection in HTML Forms
-----------------------------

It's also possible to add CSRF protection to regular HTML forms not managed by
the Symfony Form component, for example the simple forms used to delete items.
First, use the ``csrf_token()`` function in the Twig template to generate a CSRF
token and store it as a hidden field of the form:

.. code-block:: twig

<form action="{{ url('admin_post_delete', { id: post.id }) }}" method="post">
{# the argument of csrf_token() is an arbitrary value used to generate the token #}
<input type="hidden" name="token" value="{{ csrf_token('delete-item') }}" />

<button type="submit">Delete item</button>
</form>

Then, get the value of the CSRF token in the controller action and use the
:method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::isCsrfTokenValid`
to check its validity::

use Symfony\Component\HttpFoundation\Request;
// ...

public function delete(Request $request)
{
$submittedToken = $request->request->get('token');

// 'delete-item' is the same value used in the template to generate the token
if ($this->isCsrfTokenValid('delete-item', $submittedToken)) {
// ... do something, like deleting an object
}
}

.. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery
.. _`Login CSRF attacks`: https://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests
3 changes: 1 addition & 2 deletions 3 security/form_login_setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,7 @@ The form can look like anything, but it usually follows some conventions:
.. caution::

This login form is currently not protected against CSRF attacks. Read
:doc:`/security/csrf_in_login_form` on how to protect your login
form.
:doc:`/security/csrf` on how to protect your login form.

And that's it! When you submit the form, the security system will automatically
check the user's credentials and either authenticate the user or send the
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.