Merge pull request #9036 from paulbalandan/session-class

fix: Prevent invalid session handlers
This commit is contained in:
kenjis 2024-07-18 05:23:53 +09:00 committed by GitHub
commit 17d47f1d08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 5 deletions

View File

@ -75,6 +75,7 @@ use Config\Modules;
use Config\Optimize;
use Config\Pager as ConfigPager;
use Config\Services as AppServices;
use Config\Session as ConfigSession;
use Config\Toolbar as ConfigToolbar;
use Config\Validation as ConfigValidation;
use Config\View as ConfigView;
@ -130,7 +131,7 @@ use InvalidArgumentException;
* @method static Router router(RouteCollectionInterface $routes = null, Request $request = null, $getShared = true)
* @method static RouteCollection routes($getShared = true)
* @method static Security security(App $config = null, $getShared = true)
* @method static Session session(App $config = null, $getShared = true)
* @method static Session session(ConfigSession $config = null, $getShared = true)
* @method static SiteURIFactory siteurifactory(App $config = null, Superglobals $superglobals = null, $getShared = true)
* @method static Superglobals superglobals(array $server = null, array $get = null, bool $getShared = true)
* @method static Throttler throttler($getShared = true)

View File

@ -51,6 +51,7 @@ use CodeIgniter\Router\RouteCollection;
use CodeIgniter\Router\RouteCollectionInterface;
use CodeIgniter\Router\Router;
use CodeIgniter\Security\Security;
use CodeIgniter\Session\Handlers\BaseHandler as SessionBaseHandler;
use CodeIgniter\Session\Handlers\Database\MySQLiHandler;
use CodeIgniter\Session\Handlers\Database\PostgreHandler;
use CodeIgniter\Session\Handlers\DatabaseHandler;
@ -88,6 +89,7 @@ use Config\Session as SessionConfig;
use Config\Toolbar as ToolbarConfig;
use Config\Validation as ValidationConfig;
use Config\View as ViewConfig;
use InvalidArgumentException;
use Locale;
/**
@ -674,17 +676,24 @@ class Services extends BaseService
if ($driverName === DatabaseHandler::class) {
$DBGroup = $config->DBGroup ?? config(Database::class)->defaultGroup;
$db = Database::connect($DBGroup);
$driver = $db->getPlatform();
$driverPlatform = Database::connect($DBGroup)->getPlatform();
if ($driver === 'MySQLi') {
if ($driverPlatform === 'MySQLi') {
$driverName = MySQLiHandler::class;
} elseif ($driver === 'Postgre') {
} elseif ($driverPlatform === 'Postgre') {
$driverName = PostgreHandler::class;
}
}
if (! class_exists($driverName) || ! is_a($driverName, SessionBaseHandler::class, true)) {
throw new InvalidArgumentException(sprintf(
'Invalid session handler "%s" provided.',
$driverName
));
}
/** @var SessionBaseHandler $driver */
$driver = new $driverName($config, AppServices::get('request')->getIPAddress());
$driver->setLogger($logger);

View File

@ -46,6 +46,9 @@ use CodeIgniter\View\Parser;
use Config\App;
use Config\Exceptions;
use Config\Security as SecurityConfig;
use Config\Session as ConfigSession;
use InvalidArgumentException;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\PreserveGlobalState;
use PHPUnit\Framework\Attributes\RunInSeparateProcess;
@ -259,6 +262,32 @@ final class ServicesTest extends CIUnitTestCase
$this->assertInstanceOf(Session::class, $actual);
}
#[DataProvider('provideNewSessionInvalid')]
#[PreserveGlobalState(false)]
#[RunInSeparateProcess]
public function testNewSessionWithInvalidHandler(string $driver): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage(sprintf('Invalid session handler "%s" provided.', $driver));
$config = new ConfigSession();
$config->driver = $driver;
Services::session($config, false);
}
/**
* @return iterable<string, array{0: string}>
*/
public static function provideNewSessionInvalid(): iterable
{
yield 'just a string' => ['file'];
yield 'inexistent class' => ['Foo'];
yield 'other class' => [self::class];
}
#[PreserveGlobalState(false)]
#[RunInSeparateProcess]
public function testCallStatic(): void