From 95a9b8c781736b526f18d390dbafd37751265713 Mon Sep 17 00:00:00 2001 From: "Buster \"Silver Eagle\" Neece" Date: Thu, 26 Aug 2021 18:40:11 -0500 Subject: [PATCH] Enforce HTTP-only (and secure) cookies for session persistence. --- config/services.php | 22 ------------------- src/Middleware/EnforceSecurity.php | 3 --- src/Middleware/InjectSession.php | 35 ++++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/config/services.php b/config/services.php index 2e57cd5725..a50d325a62 100644 --- a/config/services.php +++ b/config/services.php @@ -219,28 +219,6 @@ function () use ( return $store; }, - // Session save handler middleware - Mezzio\Session\SessionPersistenceInterface::class => static function ( - Environment $environment, - Psr\Cache\CacheItemPoolInterface $cachePool - ) { - if ($environment->isCli()) { - $cachePool = new Symfony\Component\Cache\Adapter\ArrayAdapter(); - } - - $cachePool = new Symfony\Component\Cache\Adapter\ProxyAdapter($cachePool, 'session.'); - - return new Mezzio\Session\Cache\CacheSessionPersistence( - $cachePool, - 'app_session', - '/', - 'nocache', - 43200, - time(), - true - ); - }, - // Console App\Console\Application::class => static function ( DI\Container $di, diff --git a/src/Middleware/EnforceSecurity.php b/src/Middleware/EnforceSecurity.php index f5a2861bf8..c135ef985d 100644 --- a/src/Middleware/EnforceSecurity.php +++ b/src/Middleware/EnforceSecurity.php @@ -38,9 +38,6 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface $addHstsHeader = false; if ('https' === $request->getUri()->getScheme()) { - // Enforce secure cookies. - ini_set('session.cookie_secure', '1'); - $addHstsHeader = true; } elseif ($always_use_ssl && !$internal_api_url) { return $this->responseFactory->createResponse(307) diff --git a/src/Middleware/InjectSession.php b/src/Middleware/InjectSession.php index 23ced66ee2..0447c19323 100644 --- a/src/Middleware/InjectSession.php +++ b/src/Middleware/InjectSession.php @@ -4,26 +4,38 @@ namespace App\Middleware; +use App\Entity; use App\Environment; use App\Http\ServerRequest; use App\Session\Csrf; use App\Session\Flash; +use Mezzio\Session\Cache\CacheSessionPersistence; use Mezzio\Session\LazySession; -use Mezzio\Session\SessionPersistenceInterface; +use Psr\Cache\CacheItemPoolInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\ProxyAdapter; /** * Inject the session object into the request. */ class InjectSession implements MiddlewareInterface { + protected CacheItemPoolInterface $cachePool; + public function __construct( - protected SessionPersistenceInterface $sessionPersistence, + CacheItemPoolInterface $cachePool, + protected Entity\Repository\SettingsRepository $settingsRepo, protected Environment $environment ) { + if ($environment->isCli()) { + $cachePool = new ArrayAdapter(); + } + + $this->cachePool = new ProxyAdapter($cachePool, 'session.'); } /** @@ -32,7 +44,22 @@ public function __construct( */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { - $session = new LazySession($this->sessionPersistence, $request); + $alwaysUseSsl = $this->settingsRepo->readSettings()->getAlwaysUseSsl(); + $isHttpsUrl = ('https' === $request->getUri()->getScheme()); + + $sessionPersistence = new CacheSessionPersistence( + cache: $this->cachePool, + cookieName: 'app_session', + cookiePath: '/', + cacheLimiter: 'nocache', + cacheExpire: 43200, + lastModified: time(), + persistent: true, + cookieSecure: $alwaysUseSsl && $isHttpsUrl, + cookieHttpOnly: true + ); + + $session = new LazySession($sessionPersistence, $request); $csrf = new Csrf($session, $this->environment); Csrf::setInstance($csrf); @@ -45,6 +72,6 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface ->withAttribute(ServerRequest::ATTR_SESSION_FLASH, $flash); $response = $handler->handle($request); - return $this->sessionPersistence->persistSession($session, $response); + return $sessionPersistence->persistSession($session, $response); } }