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

Commit c75c569

Browse filesBrowse files
security #cve-2022-24895 [Security/Http] Remove CSRF tokens from storage on successful login (nicolas-grekas)
This PR was merged into the 4.4 branch.
2 parents fa1827c + 5909d74 commit c75c569
Copy full SHA for c75c569

File tree

6 files changed

+33
-7
lines changed
Filter options

6 files changed

+33
-7
lines changed

‎src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363

6464
<service id="security.authentication.session_strategy" class="Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy">
6565
<argument>%security.authentication.session_strategy.strategy%</argument>
66+
<argument type="service" id="security.csrf.token_storage" on-invalid="ignore" />
6667
</service>
6768
<service id="Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface" alias="security.authentication.session_strategy" />
6869

‎src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ class CsrfFormLoginTest extends AbstractWebTestCase
1919
public function testFormLoginAndLogoutWithCsrfTokens($config)
2020
{
2121
$client = $this->createClient(['test_case' => 'CsrfFormLogin', 'root_config' => $config]);
22+
static::$container->get('security.csrf.token_storage')->setToken('foo', 'bar');
2223

2324
$form = $client->request('GET', '/login')->selectButton('login')->form();
2425
$form['user_login[username]'] = 'johannes';
2526
$form['user_login[password]'] = 'test';
2627
$client->submit($form);
2728

29+
$this->assertFalse(static::$container->get('security.csrf.token_storage')->hasToken('foo'));
30+
2831
$this->assertRedirect($client->getResponse(), '/profile');
2932

3033
$crawler = $client->followRedirect();
@@ -48,11 +51,14 @@ public function testFormLoginAndLogoutWithCsrfTokens($config)
4851
public function testFormLoginWithInvalidCsrfToken($config)
4952
{
5053
$client = $this->createClient(['test_case' => 'CsrfFormLogin', 'root_config' => $config]);
54+
static::$container->get('security.csrf.token_storage')->setToken('foo', 'bar');
5155

5256
$form = $client->request('GET', '/login')->selectButton('login')->form();
5357
$form['user_login[_token]'] = '';
5458
$client->submit($form);
5559

60+
$this->assertTrue(static::$container->get('security.csrf.token_storage')->hasToken('foo'));
61+
5662
$this->assertRedirect($client->getResponse(), '/login');
5763

5864
$text = $client->followRedirect()->text(null, true);

‎src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php
+1-3Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,13 @@ public function testSessionLessRememberMeLogout()
3636
public function testCsrfTokensAreClearedOnLogout()
3737
{
3838
$client = $this->createClient(['test_case' => 'LogoutWithoutSessionInvalidation', 'root_config' => 'config.yml']);
39-
static::$container->get('security.csrf.token_storage')->setToken('foo', 'bar');
4039

4140
$client->request('POST', '/login', [
4241
'_username' => 'johannes',
4342
'_password' => 'test',
4443
]);
4544

46-
$this->assertTrue(static::$container->get('security.csrf.token_storage')->hasToken('foo'));
47-
$this->assertSame('bar', static::$container->get('security.csrf.token_storage')->getToken('foo'));
45+
static::$container->get('security.csrf.token_storage')->setToken('foo', 'bar');
4846

4947
$client->request('GET', '/logout');
5048

‎src/Symfony/Bundle/SecurityBundle/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/composer.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"symfony/security-core": "^4.4",
2626
"symfony/security-csrf": "^4.2|^5.0",
2727
"symfony/security-guard": "^4.2|^5.0",
28-
"symfony/security-http": "^4.4.5"
28+
"symfony/security-http": "^4.4.50"
2929
},
3030
"require-dev": {
3131
"doctrine/annotations": "^1.10.4",

‎src/Symfony/Component/Security/Http/Session/SessionAuthenticationStrategy.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Session/SessionAuthenticationStrategy.php
+11-3Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\HttpFoundation\Request;
1515
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
16+
use Symfony\Component\Security\Csrf\TokenStorage\ClearableTokenStorageInterface;
1617

1718
/**
1819
* The default session strategy implementation.
@@ -31,10 +32,15 @@ class SessionAuthenticationStrategy implements SessionAuthenticationStrategyInte
3132
public const INVALIDATE = 'invalidate';
3233

3334
private $strategy;
35+
private $csrfTokenStorage = null;
3436

35-
public function __construct(string $strategy)
37+
public function __construct(string $strategy, ClearableTokenStorageInterface $csrfTokenStorage = null)
3638
{
3739
$this->strategy = $strategy;
40+
41+
if (self::MIGRATE === $strategy) {
42+
$this->csrfTokenStorage = $csrfTokenStorage;
43+
}
3844
}
3945

4046
/**
@@ -47,10 +53,12 @@ public function onAuthentication(Request $request, TokenInterface $token)
4753
return;
4854

4955
case self::MIGRATE:
50-
// Note: this logic is duplicated in several authentication listeners
51-
// until Symfony 5.0 due to a security fix with BC compat
5256
$request->getSession()->migrate(true);
5357

58+
if ($this->csrfTokenStorage) {
59+
$this->csrfTokenStorage->clear();
60+
}
61+
5462
return;
5563

5664
case self::INVALIDATE:

‎src/Symfony/Component/Security/Http/Tests/Session/SessionAuthenticationStrategyTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Tests/Session/SessionAuthenticationStrategyTest.php
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\Session\SessionInterface;
17+
use Symfony\Component\Security\Csrf\TokenStorage\ClearableTokenStorageInterface;
1718
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
1819
use Symfony\Component\Security\Http\Tests\Fixtures\TokenInterface;
1920

@@ -57,6 +58,18 @@ public function testSessionIsInvalidated()
5758
$strategy->onAuthentication($this->getRequest($session), $this->createMock(TokenInterface::class));
5859
}
5960

61+
public function testCsrfTokensAreCleared()
62+
{
63+
$session = $this->createMock(SessionInterface::class);
64+
$session->expects($this->once())->method('migrate')->with($this->equalTo(true));
65+
66+
$csrfStorage = $this->createMock(ClearableTokenStorageInterface::class);
67+
$csrfStorage->expects($this->once())->method('clear');
68+
69+
$strategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE, $csrfStorage);
70+
$strategy->onAuthentication($this->getRequest($session), $this->createMock(TokenInterface::class));
71+
}
72+
6073
private function getRequest($session = null)
6174
{
6275
$request = $this->createMock(Request::class);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.