Skip to content

Commit 6cb95ac

Browse files
committed
Register root form types as services to support stateless CSRF protection
1 parent 8a93011 commit 6cb95ac

3 files changed

Lines changed: 106 additions & 0 deletions

File tree

config/crud.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
use Ecommit\CrudBundle\Crud\CrudFactory;
1818
use Ecommit\CrudBundle\Crud\CrudResponseGenerator;
1919
use Ecommit\CrudBundle\EventListener\MappingEntities;
20+
use Ecommit\CrudBundle\Form\Type\DisplaySettingsType;
2021
use Ecommit\CrudBundle\Form\Type\EntityAjaxType;
22+
use Ecommit\CrudBundle\Form\Type\FormSearchType;
2123
use Ecommit\CrudBundle\Twig\CrudExtension;
2224
use Symfony\Component\DependencyInjection\ServiceLocator;
2325
use Symfony\Component\Form\FormFactoryInterface;
@@ -65,5 +67,11 @@
6567
service(RouterInterface::class),
6668
])
6769
->tag('form.type')
70+
71+
->set(FormSearchType::class)
72+
->autoconfigure()
73+
74+
->set(DisplaySettingsType::class)
75+
->autoconfigure()
6876
;
6977
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the EcommitCrudBundle package.
7+
*
8+
* (c) E-commit <contact@e-commit.fr>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Ecommit\CrudBundle\Tests\Functional\App;
15+
16+
use Symfony\Component\Config\Loader\LoaderInterface;
17+
use Symfony\Component\DependencyInjection\ContainerBuilder;
18+
19+
class StatelessCsrfKernel extends Kernel
20+
{
21+
public const COOKIE_NAME = 'stateless-csrf-token';
22+
23+
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
24+
{
25+
parent::configureContainer($container, $loader);
26+
27+
$container->loadFromExtension('framework', [
28+
'csrf_protection' => [
29+
'stateless_token_ids' => ['submit'],
30+
'cookie_name' => self::COOKIE_NAME,
31+
],
32+
'form' => [
33+
'csrf_protection' => [
34+
'token_id' => 'submit',
35+
],
36+
],
37+
]);
38+
}
39+
40+
public function getCacheDir(): string
41+
{
42+
return parent::getCacheDir().'/stateless_csrf';
43+
}
44+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the EcommitCrudBundle package.
7+
*
8+
* (c) E-commit <contact@e-commit.fr>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Ecommit\CrudBundle\Tests\Functional\Controller;
15+
16+
use Ecommit\CrudBundle\Tests\Functional\App\StatelessCsrfKernel;
17+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
18+
use Symfony\Component\HttpKernel\Kernel;
19+
20+
class StatelessCsrfTest extends WebTestCase
21+
{
22+
protected function setUp(): void
23+
{
24+
if (Kernel::VERSION_ID < 70200) { // @legacy
25+
$this->markTestSkipped('The stateless CSRF protection requires Symfony 7.2 or later.');
26+
}
27+
}
28+
29+
protected static function getKernelClass(): string
30+
{
31+
return StatelessCsrfKernel::class;
32+
}
33+
34+
/**
35+
* @dataProvider getTestFormsUseStatelessCsrfTokenProvider
36+
*/
37+
public function testFormsUseStatelessCsrfToken(string $tokenId): void
38+
{
39+
$client = static::createClient();
40+
$crawler = $client->request('GET', '/user');
41+
42+
$this->assertResponseIsSuccessful();
43+
// When the token is not stateless, the value is a token stored in the session
44+
$this->assertSame(StatelessCsrfKernel::COOKIE_NAME, $crawler->filterXPath(\sprintf('//input[@id="%s"]', $tokenId))->attr('value'));
45+
}
46+
47+
public static function getTestFormsUseStatelessCsrfTokenProvider(): array
48+
{
49+
return [
50+
['crud_search_user__token'],
51+
['crud_display_settings_user__token'],
52+
];
53+
}
54+
}

0 commit comments

Comments
 (0)