From b496f073c3f03707d3531a6941dc098b84e3cbed Mon Sep 17 00:00:00 2001 From: Gunnstein Lye Date: Tue, 9 Mar 2021 13:43:42 +0100 Subject: [PATCH] Merge pull request from GHSA-gmrf-99gw-vvwj Co-authored-by: Bartek Wajda --- .../Resources/config/default_settings.yml | 4 ++++ .../Resources/config/security.yml | 2 ++ .../Server/Controller/SessionController.php | 2 +- .../Server/Security/RestAuthenticator.php | 22 ++++++++++++++++++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/eZ/Bundle/EzPublishRestBundle/Resources/config/default_settings.yml b/eZ/Bundle/EzPublishRestBundle/Resources/config/default_settings.yml index 65a5a92e18e..5a81eb54e3d 100644 --- a/eZ/Bundle/EzPublishRestBundle/Resources/config/default_settings.yml +++ b/eZ/Bundle/EzPublishRestBundle/Resources/config/default_settings.yml @@ -84,3 +84,7 @@ parameters: refreshSession: mediaType: 'UserSession' href: 'templateRouter.generate("ezpublish_rest_refreshSession", {sessionId: "{sessionId}"})' + + # Boundary times in microseconds which the authentication check will be delayed by. + ezpublish_rest.authentication_min_delay_time: 30000 + ezpublish_rest.authentication_max_delay_time: 500000 \ No newline at end of file diff --git a/eZ/Bundle/EzPublishRestBundle/Resources/config/security.yml b/eZ/Bundle/EzPublishRestBundle/Resources/config/security.yml index ab87f69b888..ed9a823c626 100644 --- a/eZ/Bundle/EzPublishRestBundle/Resources/config/security.yml +++ b/eZ/Bundle/EzPublishRestBundle/Resources/config/security.yml @@ -15,6 +15,8 @@ services: - "@ezpublish.config.resolver" - "@session.storage" - "@?logger" + - "%ezpublish_rest.authentication_min_delay_time%" + - "%ezpublish_rest.authentication_max_delay_time%" abstract: true ezpublish_rest.security.authentication.logout_handler: diff --git a/eZ/Publish/Core/REST/Server/Controller/SessionController.php b/eZ/Publish/Core/REST/Server/Controller/SessionController.php index f3ab2f175d2..39136b5b677 100644 --- a/eZ/Publish/Core/REST/Server/Controller/SessionController.php +++ b/eZ/Publish/Core/REST/Server/Controller/SessionController.php @@ -59,7 +59,7 @@ public function createSessionAction(Request $request) ) ); $request->attributes->set('username', $sessionInput->login); - $request->attributes->set('password', $sessionInput->password); + $request->attributes->set('password', (string) $sessionInput->password); try { $session = $request->getSession(); diff --git a/eZ/Publish/Core/REST/Server/Security/RestAuthenticator.php b/eZ/Publish/Core/REST/Server/Security/RestAuthenticator.php index 9f2c6c67d52..965391be8e5 100644 --- a/eZ/Publish/Core/REST/Server/Security/RestAuthenticator.php +++ b/eZ/Publish/Core/REST/Server/Security/RestAuthenticator.php @@ -36,6 +36,10 @@ */ class RestAuthenticator implements ListenerInterface, AuthenticatorInterface { + const DEFAULT_MIN_SLEEP_VALUE = 30000; + + const DEFAULT_MAX_SLEEP_VALUE = 500000; + /** @var \Psr\Log\LoggerInterface */ private $logger; @@ -59,6 +63,16 @@ class RestAuthenticator implements ListenerInterface, AuthenticatorInterface /** @var \Symfony\Component\Security\Http\Logout\LogoutHandlerInterface[] */ private $logoutHandlers = []; + /** + * @var int|null + */ + private $minSleepTime; + + /** + * @var int|null + */ + private $maxSleepTime; + public function __construct( TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, @@ -66,7 +80,9 @@ public function __construct( EventDispatcherInterface $dispatcher, ConfigResolverInterface $configResolver, SessionStorageInterface $sessionStorage, - LoggerInterface $logger = null + LoggerInterface $logger = null, + $minSleepTime = self::DEFAULT_MIN_SLEEP_VALUE, + $maxSleepTime = self::DEFAULT_MAX_SLEEP_VALUE ) { $this->tokenStorage = $tokenStorage; $this->authenticationManager = $authenticationManager; @@ -75,6 +91,8 @@ public function __construct( $this->configResolver = $configResolver; $this->sessionStorage = $sessionStorage; $this->logger = $logger; + $this->minSleepTime = !is_int($minSleepTime) ? self::DEFAULT_MIN_SLEEP_VALUE : $minSleepTime; + $this->maxSleepTime = !is_int($maxSleepTime) ? self::DEFAULT_MAX_SLEEP_VALUE : $maxSleepTime; } /** @@ -89,6 +107,8 @@ public function handle(GetResponseEvent $event) public function authenticate(Request $request) { + usleep(random_int($this->minSleepTime, $this->maxSleepTime)); + // If a token already exists and username is the same as the one we request authentication for, // then return it and mark it as coming from session. $previousToken = $this->tokenStorage->getToken();