-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement an active cookie signature algorithm upgrade path
- Loading branch information
Showing
14 changed files
with
517 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Nelmio SecurityBundle. | ||
* | ||
* (c) Nelmio <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Nelmio\SecurityBundle\EventListener; | ||
|
||
use Nelmio\SecurityBundle\SignedCookie\LegacySignatureCookieTrackerInterface; | ||
use Nelmio\SecurityBundle\SignedCookie\UpgradedCookieBuilderInterface; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\HttpKernel\Event\ResponseEvent; | ||
|
||
class SignedCookieUpgradeListener | ||
{ | ||
private LegacySignatureCookieTrackerInterface $legacySignatureCookieTracker; | ||
|
||
private UpgradedCookieBuilderInterface $upgradedCookieBuilder; | ||
|
||
public function __construct(LegacySignatureCookieTrackerInterface $legacySignatureCookieTracker, UpgradedCookieBuilderInterface $upgradedCookieBuilder) | ||
{ | ||
$this->legacySignatureCookieTracker = $legacySignatureCookieTracker; | ||
$this->upgradedCookieBuilder = $upgradedCookieBuilder; | ||
} | ||
|
||
public function onKernelResponse(ResponseEvent $event): void | ||
{ | ||
if (!$event->isMainRequest()) { | ||
return; | ||
} | ||
|
||
$response = $event->getResponse(); | ||
$request = $event->getRequest(); | ||
|
||
$currentResponseCookies = $this->extractCookieNames($response); | ||
foreach ($this->legacySignatureCookieTracker->getCookiesForUpgrade() as $name) { | ||
if (\in_array($name, $currentResponseCookies, true)) { | ||
continue; | ||
} | ||
$cookie = $this->upgradedCookieBuilder->build($name, $request->cookies->get($name)); | ||
if (null === $cookie) { | ||
continue; | ||
} | ||
|
||
$response->headers->setCookie($cookie); | ||
} | ||
} | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
private function extractCookieNames(Response $response): array | ||
{ | ||
$names = []; | ||
$cookies = $response->headers->getCookies(); | ||
foreach ($cookies as $cookie) { | ||
$names[] = $cookie->getName(); | ||
} | ||
|
||
return $names; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Nelmio SecurityBundle. | ||
* | ||
* (c) Nelmio <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Nelmio\SecurityBundle\SignedCookie; | ||
|
||
class LegacySignatureCookieTracker implements LegacySignatureCookieTrackerInterface | ||
{ | ||
/** | ||
* @var string[] | ||
*/ | ||
private array $names = []; | ||
|
||
public function flagForUpgrade(string $cookieName): void | ||
{ | ||
if (\in_array($cookieName, $this->names, true)) { | ||
return; | ||
} | ||
$this->names[] = $cookieName; | ||
} | ||
|
||
public function getCookiesForUpgrade(): array | ||
{ | ||
return $this->names; | ||
} | ||
|
||
public function clear(): void | ||
{ | ||
$this->names = []; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/SignedCookie/LegacySignatureCookieTrackerInterface.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Nelmio SecurityBundle. | ||
* | ||
* (c) Nelmio <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Nelmio\SecurityBundle\SignedCookie; | ||
|
||
interface LegacySignatureCookieTrackerInterface | ||
{ | ||
public function flagForUpgrade(string $cookieName): void; | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
public function getCookiesForUpgrade(): array; | ||
|
||
public function clear(): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Nelmio SecurityBundle. | ||
* | ||
* (c) Nelmio <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Nelmio\SecurityBundle\SignedCookie; | ||
|
||
interface SignatureUpgradeCheckerInterface | ||
{ | ||
public function needsUpgrade(string $signedValue): bool; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Nelmio SecurityBundle. | ||
* | ||
* (c) Nelmio <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Nelmio\SecurityBundle\SignedCookie; | ||
|
||
use Symfony\Component\HttpFoundation\Cookie; | ||
|
||
interface UpgradedCookieBuilderInterface | ||
{ | ||
public function build(string $name, ?string $value): ?Cookie; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Nelmio SecurityBundle. | ||
* | ||
* (c) Nelmio <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Nelmio\SecurityBundle\SignedCookie; | ||
|
||
use Symfony\Component\HttpFoundation\Cookie; | ||
|
||
class UpgradedCookieBuilderRegistry implements UpgradedCookieBuilderInterface | ||
{ | ||
/** | ||
* @var iterable<UpgradedCookieBuilderInterface> | ||
*/ | ||
private iterable $builders; | ||
|
||
/** | ||
* @param iterable<UpgradedCookieBuilderInterface> $builders | ||
*/ | ||
public function __construct(iterable $builders) | ||
{ | ||
$this->builders = $builders; | ||
} | ||
|
||
public function build(string $name, ?string $value): ?Cookie | ||
{ | ||
foreach ($this->builders as $builder) { | ||
$cookie = $builder->build($name, $value); | ||
if (null !== $cookie) { | ||
return $cookie; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.