CVE-2022-24895 (PHP, published 2023-02-03T22:15Z)
Description: value: Symfony is a PHP framework for web and console applications and a set of reusable PHP components. When authenticating users Symfony by default regenerates the session ID upon login, but preserves the rest of session attributes. Because this does not clear CSRF tokens upon login, this might enables same-site attackers to bypass the CSRF protection mechanism by performing an attack similar to a session-fixation. This issue has been fixed in the 4.4 branch. 


Severity: nan (CVSS v3 base score: 8.8)
Weakness: CWE-384 \u2014 Session Fixation
Authenticating a user, or otherwise establishing a new user session, without invalidating any existing session identifier gives an attacker the opportunity to steal authenticated sessions.
Repository: https://github.com/symfony/symfony
Files changed:
src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php
src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php
src/Symfony/Bundle/SecurityBundle/composer.json
src/Symfony/Component/Security/Http/Session/SessionAuthenticationStrategy.php
src/Symfony/Component/Security/Http/Tests/Session/SessionAuthenticationStrategyTest.php
Commit message: [Security/Http] Remove CSRF tokens from storage on successful login


Vulnerable code:
        static::$container->get('security.csrf.token_storage')->setToken('foo', 'bar');
        $this->assertTrue(static::$container->get('security.csrf.token_storage')->hasToken('foo'));
        $this->assertSame('bar', static::$container->get('security.csrf.token_storage')->getToken('foo'));
        "symfony/security-http": "^4.4.5"
    public function __construct(string $strategy)
                // Note: this logic is duplicated in several authentication listeners
                // until Symfony 5.0 due to a security fix with BC compat

Fixed code:
            <argument type="service" id="security.csrf.token_storage" on-invalid="ignore" />
        static::$container->get('security.csrf.token_storage')->setToken('foo', 'bar');
        $this->assertFalse(static::$container->get('security.csrf.token_storage')->hasToken('foo'));

        static::$container->get('security.csrf.token_storage')->setToken('foo', 'bar');
        $this->assertTrue(static::$container->get('security.csrf.token_storage')->hasToken('foo'));

        static::$container->get('security.csrf.token_storage')->setToken('foo', 'bar');
        "symfony/security-http": "^4.4.50"
use Symfony\Component\Security\Csrf\TokenStorage\ClearableTokenStorageInterface;
    private $csrfTokenStorage = null;
    public function __construct(string $strategy, ClearableTokenStorageInterface $csrfTokenStorage = null)

        if (self::MIGRATE === $strategy) {
            $this->csrfTokenStorage = $csrfTokenStorage;
        }
                if ($this->csrfTokenStorage) {
                    $this->csrfTokenStorage->clear();
                }

use Symfony\Component\Security\Csrf\TokenStorage\ClearableTokenStorageInterface;
    public function testCsrfTokensAreCleared()
    {
        $session = $this->createMock(SessionInterface::class);
        $session->expects($this->once())->method('migrate')->with($this->equalTo(true));

        $csrfStorage = $this->createMock(ClearableTokenStorageInterface::class);
        $csrfStorage->expects($this->once())->method('clear');

        $strategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE, $csrfStorage);
        $strategy->onAuthentication($this->getRequest($session), $this->createMock(TokenInterface::class));
    }