Replace exit with exception in Session class

Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
Maurício Meneghini Fauth 2022-11-17 22:06:51 -03:00
parent a5dd1b6b4c
commit 6122dfd0be
No known key found for this signature in database
GPG Key ID: 6A16FD38AFC89CC8
5 changed files with 61 additions and 40 deletions

View File

@ -11,6 +11,7 @@ use PhpMyAdmin\Dbal\TableName;
use PhpMyAdmin\Exceptions\AuthenticationPluginException;
use PhpMyAdmin\Exceptions\ConfigException;
use PhpMyAdmin\Exceptions\MissingExtensionException;
use PhpMyAdmin\Exceptions\SessionHandlerException;
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\Plugins\AuthenticationPlugin;
@ -127,8 +128,14 @@ final class Common
}
if ($route !== '/messages') {
// Include session handling after the globals, to prevent overwriting.
Session::setUp($config, $errorHandler);
try {
// Include session handling after the globals, to prevent overwriting.
Session::setUp($config, $errorHandler);
} catch (SessionHandlerException $exception) {
echo self::getGenericError($exception->getMessage());
return;
}
}
$request = Core::populateRequestWithEncryptedQueryParams($request);

View File

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Exceptions;
use Exception;
class SessionHandlerException extends Exception
{
}

View File

@ -10,12 +10,14 @@ namespace PhpMyAdmin\Plugins\Auth;
use PhpMyAdmin\Common;
use PhpMyAdmin\Config;
use PhpMyAdmin\Core;
use PhpMyAdmin\Exceptions\SessionHandlerException;
use PhpMyAdmin\LanguageManager;
use PhpMyAdmin\Message;
use PhpMyAdmin\Plugins\AuthenticationPlugin;
use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Server\Select;
use PhpMyAdmin\Session;
use PhpMyAdmin\Template;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
use PhpMyAdmin\Utils\SessionCache;
@ -327,8 +329,18 @@ class AuthenticationCookie extends AuthenticationPlugin
$GLOBALS['pma_auth_server'] = Core::sanitizeMySQLHost($_REQUEST['pma_servername']);
}
/* Secure current session on login to avoid session fixation */
Session::secure();
try {
/* Secure current session on login to avoid session fixation */
Session::secure();
} catch (SessionHandlerException $exception) {
echo (new Template())->render('error/generic', [
'lang' => $GLOBALS['lang'] ?? 'en',
'dir' => $GLOBALS['text_dir'] ?? 'ltr',
'error_message' => $exception->getMessage(),
]);
exit;
}
return true;
}

View File

@ -9,6 +9,7 @@ namespace PhpMyAdmin\Plugins;
use PhpMyAdmin\Config;
use PhpMyAdmin\Core;
use PhpMyAdmin\Exceptions\SessionHandlerException;
use PhpMyAdmin\IpAllowDeny;
use PhpMyAdmin\Logging;
use PhpMyAdmin\Message;
@ -248,7 +249,18 @@ abstract class AuthenticationPlugin
/* Show login form (this exits) */
if (! $success) {
/* Force generating of new session */
Session::secure();
try {
Session::secure();
} catch (SessionHandlerException $exception) {
echo (new Template())->render('error/generic', [
'lang' => $GLOBALS['lang'] ?? 'en',
'dir' => $GLOBALS['text_dir'] ?? 'ltr',
'error_message' => $exception->getMessage(),
]);
exit;
}
$this->showLoginForm();
}

View File

@ -1,15 +1,11 @@
<?php
/**
* Session handling
*
* @see https://www.php.net/manual/en/features.sessions.php
*/
declare(strict_types=1);
namespace PhpMyAdmin;
use function defined;
use PhpMyAdmin\Exceptions\SessionHandlerException;
use function htmlspecialchars;
use function implode;
use function ini_get;
@ -32,13 +28,12 @@ use function setcookie;
use const PHP_SESSION_ACTIVE;
use const PHP_VERSION_ID;
/**
* Session class
*/
class Session
{
/**
* Generates PMA_token session variable.
*
* @throws SessionHandlerException
*/
private static function generateToken(): void
{
@ -53,19 +48,15 @@ class Session
return;
}
echo (new Template())->render('error/generic', [
'lang' => $GLOBALS['lang'] ?? 'en',
'dir' => $GLOBALS['text_dir'] ?? 'ltr',
'error_message' => 'Failed to generate random CSRF token!',
]);
exit;
throw new SessionHandlerException('Failed to generate random CSRF token!');
}
/**
* tries to secure session from hijacking and fixation
* should be called before login and after successful login
* (only required if sensitive information stored in session)
*
* @throws SessionHandlerException
*/
public static function secure(): void
{
@ -83,6 +74,8 @@ class Session
* Session failed function
*
* @param array $errors PhpMyAdmin\ErrorHandler array
*
* @throws SessionHandlerException
*/
private static function sessionFailed(array $errors): void
{
@ -114,20 +107,12 @@ class Session
. 'in your browser.'
. '<br><br>'
. implode('<br><br>', $messages);
echo (new Template())->render('error/generic', [
'lang' => $GLOBALS['lang'] ?? 'en',
'dir' => $GLOBALS['text_dir'] ?? 'ltr',
'error_message' => $errorMessage,
]);
exit;
throw new SessionHandlerException($errorMessage);
}
/**
* Set up session
*
* @param Config $config Configuration handler
* @param ErrorHandler $errorHandler Error handler
* @throws SessionHandlerException
*/
public static function setUp(Config $config, ErrorHandler $errorHandler): void
{
@ -251,14 +236,8 @@ class Session
return;
}
echo (new Template())->render('error/generic', [
'lang' => $GLOBALS['lang'] ?? 'en',
'dir' => $GLOBALS['text_dir'] ?? 'ltr',
'error_message' => 'Failed to store CSRF token in session! Probably sessions are not working properly.',
]);
if (! defined('TESTSUITE')) {
exit;
}
throw new SessionHandlerException(
'Failed to store CSRF token in session! Probably sessions are not working properly.'
);
}
}