getNativeConnection(), [ 'db_table' => 'kimai2_sessions', 'db_id_col' => 'id', 'db_data_col' => 'data', 'db_lifetime_col' => 'lifetime', 'db_time_col' => 'time', 'lock_mode' => PdoSessionHandler::LOCK_ADVISORY, ]); } public function garbageCollection(): void { $connection = $this->getConnection(); $sql = 'DELETE FROM kimai2_sessions WHERE lifetime < :time'; $stmt = $connection->prepare($sql); $stmt->bindValue(':time', time(), \PDO::PARAM_INT); $stmt->execute(); } public function validateId(#[\SensitiveParameter] string $sessionId): bool { $result = parent::validateId($sessionId); if ($result === false) { $limiter = $this->sessionPredictionLimiter->create($this->requestStack->getMainRequest()?->getClientIp()); $limit = $limiter->consume(); if (false === $limit->isAccepted()) { throw new BadRequestHttpException('Too many requests with invalid Session ID. Prediction attack?'); } usleep(250000); // slow down potential attacks } return $result; } }