VYPR
Moderate severityNVD Advisory· Published Jun 17, 2021· Updated Aug 3, 2024

Authentication granted with multiple firewalls

CVE-2021-32693

Description

Symfony is a PHP framework for web and console applications and a set of reusable PHP components. A vulnerability related to firewall authentication is in Symfony starting with version 5.3.0 and prior to 5.3.2. When an application defines multiple firewalls, the token authenticated by one of the firewalls was available for all other firewalls. This could be abused when the application defines different providers for each part of the application, in such a situation, a user authenticated on a part of the application could be considered authenticated on the rest of the application. Starting in version 5.3.2, a patch ensures that the authenticated token is only available for the firewall that generates it.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
symfony/security-httpPackagist
>= 5.3.0, < 5.3.25.3.2
symfony/symfonyPackagist
>= 5.3.0, < 5.3.25.3.2

Affected products

1

Patches

2
6bf4c3121977

security #cve-2021-32693 [SecurityHttp] Fix "Authentication granted with multiple firewalls" (wouterj)

https://github.com/symfony/security-httpNicolas GrekasJun 17, 2021via ghsa
2 files changed · +5 5
  • Firewall/ContextListener.php+2 2 modified
    @@ -95,7 +95,7 @@ public function authenticate(RequestEvent $event)
             $request = $event->getRequest();
             $session = $request->hasPreviousSession() && $request->hasSession() ? $request->getSession() : null;
     
    -        $request->attributes->set('_security_firewall_run', true);
    +        $request->attributes->set('_security_firewall_run', $this->sessionKey);
     
             if (null !== $session) {
                 $usageIndexValue = $session instanceof Session ? $usageIndexReference = &$session->getUsageIndex() : 0;
    @@ -169,7 +169,7 @@ public function onKernelResponse(ResponseEvent $event)
     
             $request = $event->getRequest();
     
    -        if (!$request->hasSession() || !$request->attributes->get('_security_firewall_run', false)) {
    +        if (!$request->hasSession() || $request->attributes->get('_security_firewall_run') !== $this->sessionKey) {
                 return;
             }
     
    
  • Tests/Firewall/ContextListenerTest.php+3 3 modified
    @@ -106,7 +106,7 @@ public function testOnKernelResponseWithoutSession()
             $tokenStorage = new TokenStorage();
             $tokenStorage->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit'));
             $request = new Request();
    -        $request->attributes->set('_security_firewall_run', true);
    +        $request->attributes->set('_security_firewall_run', '_security_session');
             $session = new Session(new MockArraySessionStorage());
             $request->setSession($session);
     
    @@ -212,7 +212,7 @@ public function testOnKernelResponseListenerRemovesItself()
             $listener = new ContextListener($tokenStorage, [], 'key123', null, $dispatcher);
     
             $request = new Request();
    -        $request->attributes->set('_security_firewall_run', true);
    +        $request->attributes->set('_security_firewall_run', '_security_key123');
             $request->setSession($session);
     
             $event = new ResponseEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST, new Response());
    @@ -370,7 +370,7 @@ protected function runSessionOnKernelResponse($newToken, $original = null)
         {
             $session = new Session(new MockArraySessionStorage());
             $request = new Request();
    -        $request->attributes->set('_security_firewall_run', true);
    +        $request->attributes->set('_security_firewall_run', '_security_session');
             $request->setSession($session);
             $requestStack = new RequestStack();
             $requestStack->push($request);
    
3084764ad82f

Only trigger for the correct firewall in ContextListener::onKernelResponse()

https://github.com/symfony/symfonyWouter de JongJun 3, 2021via ghsa
6 files changed · +44 6
  • src/Symfony/Bundle/SecurityBundle/composer.json+1 1 modified
    @@ -29,7 +29,7 @@
             "symfony/security-core": "^5.3",
             "symfony/security-csrf": "^4.4|^5.0",
             "symfony/security-guard": "^5.3",
    -        "symfony/security-http": "^5.3"
    +        "symfony/security-http": "^5.3.2"
         },
         "require-dev": {
             "doctrine/annotations": "^1.10.4",
    
  • src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewalls.yml+17 0 added
    @@ -0,0 +1,17 @@
    +imports:
    +- { resource: ./config.yml }
    +- { resource: ./security.yml }
    +
    +security:
    +    enable_authenticator_manager: true
    +    firewalls:
    +        firewall1:
    +            pattern: /firewall1
    +            provider: in_memory
    +            form_login:
    +                check_path: /firewall1/login
    +        firewall2:
    +            pattern: /firewall2
    +            provider: in_memory2
    +            form_login:
    +                check_path: /firewall2/login
    
  • src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml+8 0 modified
    @@ -18,3 +18,11 @@ security_main_profile:
     security_custom_profile:
         path:     /custom/user_profile
         defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::profileAction }
    +
    +firewall1_login:
    +    path: /firewall1/login
    +
    +firewall2_profile:
    +    path: /firewall2/profile
    +    defaults:
    +        _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\ProfileController
    
  • src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php+13 0 modified
    @@ -87,4 +87,17 @@ public function provideEmailsWithFirewalls()
             yield ['jane@example.org', 'main'];
             yield ['john@example.org', 'custom'];
         }
    +
    +    public function testMultipleFirewalls()
    +    {
    +        $client = $this->createClient(['test_case' => 'Authenticator', 'root_config' => 'multiple_firewalls.yml']);
    +
    +        $client->request('POST', '/firewall1/login', [
    +            '_username' => 'jane@example.org',
    +            '_password' => 'test',
    +        ]);
    +
    +        $client->request('GET', '/firewall2/profile');
    +        $this->assertResponseRedirects('http://localhost/login');
    +    }
     }
    
  • src/Symfony/Component/Security/Http/Firewall/ContextListener.php+2 2 modified
    @@ -95,7 +95,7 @@ public function authenticate(RequestEvent $event)
             $request = $event->getRequest();
             $session = $request->hasPreviousSession() && $request->hasSession() ? $request->getSession() : null;
     
    -        $request->attributes->set('_security_firewall_run', true);
    +        $request->attributes->set('_security_firewall_run', $this->sessionKey);
     
             if (null !== $session) {
                 $usageIndexValue = $session instanceof Session ? $usageIndexReference = &$session->getUsageIndex() : 0;
    @@ -169,7 +169,7 @@ public function onKernelResponse(ResponseEvent $event)
     
             $request = $event->getRequest();
     
    -        if (!$request->hasSession() || !$request->attributes->get('_security_firewall_run', false)) {
    +        if (!$request->hasSession() || $request->attributes->get('_security_firewall_run') !== $this->sessionKey) {
                 return;
             }
     
    
  • src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php+3 3 modified
    @@ -106,7 +106,7 @@ public function testOnKernelResponseWithoutSession()
             $tokenStorage = new TokenStorage();
             $tokenStorage->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit'));
             $request = new Request();
    -        $request->attributes->set('_security_firewall_run', true);
    +        $request->attributes->set('_security_firewall_run', '_security_session');
             $session = new Session(new MockArraySessionStorage());
             $request->setSession($session);
     
    @@ -212,7 +212,7 @@ public function testOnKernelResponseListenerRemovesItself()
             $listener = new ContextListener($tokenStorage, [], 'key123', null, $dispatcher);
     
             $request = new Request();
    -        $request->attributes->set('_security_firewall_run', true);
    +        $request->attributes->set('_security_firewall_run', '_security_key123');
             $request->setSession($session);
     
             $event = new ResponseEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST, new Response());
    @@ -370,7 +370,7 @@ protected function runSessionOnKernelResponse($newToken, $original = null)
         {
             $session = new Session(new MockArraySessionStorage());
             $request = new Request();
    -        $request->attributes->set('_security_firewall_run', true);
    +        $request->attributes->set('_security_firewall_run', '_security_session');
             $request->setSession($session);
             $requestStack = new RequestStack();
             $requestStack->push($request);
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.