Skip to content

Commit f2312e5

Browse files
committed
Enable CSRF protection by default
1 parent f7a7e56 commit f2312e5

7 files changed

Lines changed: 35 additions & 5 deletions

File tree

doc/upgrade/3.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@
161161
* [Création d'un formulaire de recherche](../crud.md#ajout-formulaire-de-recherche-facultatif)
162162
* [Options du formulaire de recherche](../references/searcher.md)
163163
* [Personnalisation avancée de la classe Searcher](../cookbook/advanced-searcher.md)
164+
* La protection CSRF est maintenant activée sur le formulaire de recherche (`FormSearchType`). Le jeton CSRF est
165+
automatiquement rendu par la fonction Twig `crud_search_form_start`. Si vous surchargez le bloc Twig
166+
`search_form_start` ou si vous n'utilisez pas cette fonction Twig, vous devez rendre vous-même le champ `_token`
167+
du formulaire.
164168

165169

166170

@@ -254,6 +258,8 @@ Si vous utilisez l'une de ces classes, voici la migration à effectuer :
254258
* Ajout de l'option requise `reset_settings_url`.
255259
* L'option `resultsPerPageChoices` est renommée en `results_per_page_choices`.
256260
* L'option `columnsChoices` est renommée en `columns_choices`.
261+
* La protection CSRF est maintenant activée. Le jeton CSRF est automatiquement rendu par le thème Twig
262+
(via `form_end`).
257263

258264

259265

src/Form/Type/DisplaySettingsType.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
7070

7171
public function configureOptions(OptionsResolver $resolver): void
7272
{
73-
$resolver->setDefaults([
74-
'csrf_protection' => false,
75-
]);
76-
7773
$resolver->setRequired([
7874
'results_per_page_choices',
7975
'columns_choices',

src/Form/Type/FormSearchType.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ public function configureOptions(OptionsResolver $resolver): void
2727
{
2828
$resolver->setDefaults([
2929
'data_class' => 'Ecommit\CrudBundle\Form\Searcher\SearcherInterface',
30-
'csrf_protection' => false,
3130
]);
3231
}
3332

templates/Theme/base.html.twig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@
232232
{% set form_attr = form_attr|merge({novalidate: 'novalidate'}) %}
233233
{% endif %}
234234
{{ form_start(crud.searchForm, {'attr': form_attr}) }}
235+
{# The CSRF token is rendered here because templates may close the form with a raw "</form>" tag (without form_end) #}
236+
{% if crud.searchForm._token is defined %}
237+
{{ form_widget(crud.searchForm._token) }}
238+
{% endif %}
235239
{% endapply %}
236240
{% endblock %}
237241

tests/Crud/AbstractCrudTestCase.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,21 @@
2424
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
2525
use Symfony\Component\HttpFoundation\Request;
2626
use Symfony\Component\HttpFoundation\RequestStack;
27+
use Symfony\Component\HttpFoundation\Session\Session;
2728
use Symfony\Component\HttpFoundation\Session\SessionInterface;
29+
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
2830

2931
abstract class AbstractCrudTestCase extends KernelTestCase
3032
{
3133
protected function setUp(): void
3234
{
3335
self::bootKernel();
36+
37+
// The real form factory renders the CSRF token using the real "request_stack" service.
38+
// Push a request with a session so CSRF token generation does not fail.
39+
$realRequest = new Request();
40+
$realRequest->setSession(new Session(new MockArraySessionStorage()));
41+
static::getContainer()->get('request_stack')->push($realRequest);
3442
}
3543

3644
protected function createCrud(array|CrudConfig $crudConfig, array $filters = [], mixed $sessionValue = null): Crud

tests/Form/Filter/AbstractFilterTestCase.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
use Symfony\Component\Form\FormView;
2929
use Symfony\Component\HttpFoundation\Request;
3030
use Symfony\Component\HttpFoundation\RequestStack;
31+
use Symfony\Component\HttpFoundation\Session\Session;
3132
use Symfony\Component\HttpFoundation\Session\SessionInterface;
33+
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
3234

3335
abstract class AbstractFilterTestCase extends KernelTestCase
3436
{
@@ -54,6 +56,12 @@ protected function setUp(): void
5456
$this->em = static::getContainer()->get(ManagerRegistry::class)->getManager();
5557
$this->factory = static::getContainer()->get(FormFactoryInterface::class);
5658

59+
// The real form factory renders the CSRF token using the real "request_stack" service.
60+
// Push a request with a session so CSRF token generation does not fail.
61+
$realRequest = new Request();
62+
$realRequest->setSession(new Session(new MockArraySessionStorage()));
63+
static::getContainer()->get('request_stack')->push($realRequest);
64+
5765
$session = $this->createMock(SessionInterface::class);
5866
$session->expects($this->any())
5967
->method('get')

tests/Twig/CrudExtensionTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
use Symfony\Component\Form\Extension\Core\Type\FormType;
2424
use Symfony\Component\Form\FormFactoryInterface;
2525
use Symfony\Component\Form\FormView;
26+
use Symfony\Component\HttpFoundation\Request;
27+
use Symfony\Component\HttpFoundation\Session\Session;
28+
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
2629
use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
2730
use Twig\Environment;
2831
use Twig\Markup;
@@ -51,6 +54,12 @@ protected function setUp(): void
5154
$this->crudExtension = self::getContainer()->get('ecommit_crud.twig.crud_extension');
5255
$this->formFactory = self::getContainer()->get(FormFactoryInterface::class);
5356
$this->environment = self::getContainer()->get(Environment::class);
57+
58+
// The real form factory renders the CSRF token using the real "request_stack" service.
59+
// Push a request with a session so CSRF token generation does not fail.
60+
$realRequest = new Request();
61+
$realRequest->setSession(new Session(new MockArraySessionStorage()));
62+
self::getContainer()->get('request_stack')->push($realRequest);
5463
}
5564

5665
public function testFormStartAjax(): void

0 commit comments

Comments
 (0)