diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 605eaf1628..fce78bfda7 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6990,12 +6990,6 @@ parameters: count: 1 path: src/Http/Middleware/StatementHistory.php - - - message: '#^Parameter \#1 \$known_string of function hash_equals expects string, mixed given\.$#' - identifier: argument.type - count: 1 - path: src/Http/Middleware/TokenRequestParamChecking.php - - message: '#^Method PhpMyAdmin\\Http\\ServerRequest\:\:getAttributes\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue @@ -11619,12 +11613,6 @@ parameters: count: 1 path: src/Server/SysInfo/WindowsNt.php - - - message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#' - identifier: empty.notAllowed - count: 3 - path: src/Session.php - - message: '#^Only booleans are allowed in &&, string\|false given on the left side\.$#' identifier: booleanAnd.leftNotBoolean diff --git a/psalm-baseline.xml b/psalm-baseline.xml index ae8eb97993..4843ef5104 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -4897,11 +4897,6 @@ - - - - - @@ -8466,7 +8461,6 @@ - diff --git a/src/Controllers/Setup/HomeController.php b/src/Controllers/Setup/HomeController.php index 8c4cb999fb..0824538ee2 100644 --- a/src/Controllers/Setup/HomeController.php +++ b/src/Controllers/Setup/HomeController.php @@ -14,6 +14,7 @@ use PhpMyAdmin\Http\Response; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\I18n\LanguageManager; use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\Session; use PhpMyAdmin\Setup\Index; use PhpMyAdmin\Setup\SetupHelper; use PhpMyAdmin\Template; @@ -104,7 +105,7 @@ final class HomeController implements InvocableController 'auth_type' => $configFile->getValue('Servers/' . $id . '/auth_type'), 'dsn' => $configFile->getServerDSN($id), 'params' => [ - 'token' => $_SESSION[' PMA_token '], + 'token' => Session::getToken(), 'edit' => ['page' => 'servers', 'mode' => 'edit', 'id' => $id], 'remove' => ['page' => 'servers', 'mode' => 'remove', 'id' => $id], ], diff --git a/src/Header.php b/src/Header.php index e6c85575b3..fabc460cbc 100644 --- a/src/Header.php +++ b/src/Header.php @@ -122,7 +122,7 @@ class Header 'server' => Current::$server, 'table' => Current::$table, 'db' => Current::$database, - 'token' => $_SESSION[' PMA_token '], + 'token' => Session::getToken(), 'text_dir' => LanguageManager::$textDirection->value, 'LimitChars' => $this->config->config->limitChars, 'pftext' => $pftext, diff --git a/src/Http/Middleware/TokenRequestParamChecking.php b/src/Http/Middleware/TokenRequestParamChecking.php index 6958671cc7..1179730ffd 100644 --- a/src/Http/Middleware/TokenRequestParamChecking.php +++ b/src/Http/Middleware/TokenRequestParamChecking.php @@ -8,6 +8,7 @@ use PhpMyAdmin\Exceptions\MismatchedSessionId; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Message; use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\Session; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; @@ -49,7 +50,7 @@ final readonly class TokenRequestParamChecking implements MiddlewareInterface public function checkTokenRequestParam(ServerRequest $request): ResponseInterface|null { $token = $request->getParsedBodyParamAsString('token', ''); - if ($token !== '' && hash_equals($_SESSION[' PMA_token '], $token)) { + if ($token !== '' && hash_equals(Session::getToken(), $token)) { return null; } diff --git a/src/Plugins/Auth/AuthenticationCookie.php b/src/Plugins/Auth/AuthenticationCookie.php index 88400e1481..1008c5f1e6 100644 --- a/src/Plugins/Auth/AuthenticationCookie.php +++ b/src/Plugins/Auth/AuthenticationCookie.php @@ -88,7 +88,7 @@ class AuthenticationCookie extends AuthenticationPlugin */ if ($sessionExpired) { $this->responseRenderer->setRequestStatus(false); - $this->responseRenderer->addJSON('new_token', $_SESSION[' PMA_token ']); + $this->responseRenderer->addJSON('new_token', Session::getToken()); } /** @@ -453,7 +453,7 @@ class AuthenticationCookie extends AuthenticationPlugin if (isset($_REQUEST['session_timedout'])) { $this->responseRenderer->addJSON('logged_in', 1); $this->responseRenderer->addJSON('success', 1); - $this->responseRenderer->addJSON('new_token', $_SESSION[' PMA_token ']); + $this->responseRenderer->addJSON('new_token', Session::getToken()); return $this->responseRenderer->response(); } diff --git a/src/Session.php b/src/Session.php index d4556eecb2..c6217411e5 100644 --- a/src/Session.php +++ b/src/Session.php @@ -12,6 +12,7 @@ use function htmlspecialchars; use function implode; use function ini_get; use function ini_set; +use function is_string; use function preg_replace; use function session_abort; use function session_cache_limiter; @@ -38,6 +39,10 @@ class Session */ private static function generateToken(): void { + /** + * Token which is used for authenticating access queries. + * (we use "space PMA_token space" to prevent overwriting) + */ $_SESSION[' PMA_token '] = Util::generateRandom(16, true); $_SESSION[' HMAC_secret '] = Util::generateRandom(16); @@ -45,13 +50,22 @@ class Session * Check if token is properly generated (the generation can fail, for example * due to missing /dev/random for openssl). */ - if (! empty($_SESSION[' PMA_token '])) { + if (self::getToken() !== '') { return; } throw new SessionHandlerException('Failed to generate random CSRF token!'); } + public static function getToken(): string + { + if (isset($_SESSION[' PMA_token ']) && is_string($_SESSION[' PMA_token '])) { + return $_SESSION[' PMA_token ']; + } + + return ''; + } + /** * tries to secure session from hijacking and fixation * should be called before login and after successful login @@ -192,11 +206,7 @@ class Session self::sessionFailed($errors); } - /** - * Token which is used for authenticating access queries. - * (we use "space PMA_token space" to prevent overwriting) - */ - if (! empty($_SESSION[' PMA_token '])) { + if (self::getToken() !== '') { return; } @@ -219,7 +229,7 @@ class Session // A third cookie will be sent by session_regenerate_id() which will override these two session_start(); - if (! empty($_SESSION[' PMA_token '])) { + if (self::getToken() !== '') { return; } diff --git a/src/Url.php b/src/Url.php index 20e968fe60..68a0b4ef54 100644 --- a/src/Url.php +++ b/src/Url.php @@ -124,8 +124,9 @@ class Url $fields = ''; /* Always include token in plain forms */ - if ($isToken === false && isset($_SESSION[' PMA_token '])) { - $values['token'] = $_SESSION[' PMA_token ']; + $token = Session::getToken(); + if ($isToken === false && $token !== '') { + $values['token'] = $token; } foreach ($values as $name => $value) {