From 2d58ed9d195e7f18d97842d112e019121487914c Mon Sep 17 00:00:00 2001 From: Dave Smith-Hayes Date: Mon, 2 Dec 2024 17:42:06 +0000 Subject: [PATCH] Add the form key middleware to registering the user --- app/composer.lock | 65 ++++++++++--------- .../Controller/User/RegisterUserAction.php | 1 - app/src/Middleware/FormKeyMiddleware.php | 21 ++++-- app/src/Routes.php | 3 + 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/app/composer.lock b/app/composer.lock index 1fce2ab..d0486b7 100644 --- a/app/composer.lock +++ b/app/composer.lock @@ -3224,16 +3224,16 @@ }, { "name": "symfony/config", - "version": "v7.1.7", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "dc373a5cbd345354696f5dfd39c5c7a8ea23f4c8" + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/dc373a5cbd345354696f5dfd39c5c7a8ea23f4c8", - "reference": "dc373a5cbd345354696f5dfd39c5c7a8ea23f4c8", + "url": "https://api.github.com/repos/symfony/config/zipball/bcd3c4adf0144dee5011bb35454728c38adec055", + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055", "shasum": "" }, "require": { @@ -3279,7 +3279,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.1.7" + "source": "https://github.com/symfony/config/tree/v7.2.0" }, "funding": [ { @@ -3295,20 +3295,20 @@ "type": "tidelift" } ], - "time": "2024-11-04T11:34:07+00:00" + "time": "2024-11-04T11:36:24+00:00" }, { "name": "symfony/console", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5" + "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ff04e5b5ba043d2badfb308197b9e6b42883fcd5", - "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5", + "url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", + "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", "shasum": "" }, "require": { @@ -3372,7 +3372,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.8" + "source": "https://github.com/symfony/console/tree/v7.2.0" }, "funding": [ { @@ -3388,7 +3388,7 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:23:19+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3459,16 +3459,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4" + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/c835867b3c62bb05c7fe3d637c871c7ae52024d4", - "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", "shasum": "" }, "require": { @@ -3505,7 +3505,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.6" + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" }, "funding": [ { @@ -3521,7 +3521,7 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:11:02+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4082,16 +4082,16 @@ }, { "name": "symfony/string", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/591ebd41565f356fcd8b090fe64dbb5878f50281", - "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { @@ -4149,7 +4149,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.8" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -4165,20 +4165,20 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:21+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "twig/twig", - "version": "v3.15.0", + "version": "v3.16.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "2d5b3964cc21d0188633d7ddce732dc8e874db02" + "reference": "475ad2dc97d65d8631393e721e7e44fb544f0561" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/2d5b3964cc21d0188633d7ddce732dc8e874db02", - "reference": "2d5b3964cc21d0188633d7ddce732dc8e874db02", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/475ad2dc97d65d8631393e721e7e44fb544f0561", + "reference": "475ad2dc97d65d8631393e721e7e44fb544f0561", "shasum": "" }, "require": { @@ -4189,6 +4189,7 @@ "symfony/polyfill-php81": "^1.29" }, "require-dev": { + "phpstan/phpstan": "^2.0", "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, @@ -4232,7 +4233,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.15.0" + "source": "https://github.com/twigphp/Twig/tree/v3.16.0" }, "funding": [ { @@ -4244,7 +4245,7 @@ "type": "tidelift" } ], - "time": "2024-11-17T15:59:19+00:00" + "time": "2024-11-29T08:27:05+00:00" }, { "name": "vlucas/phpdotenv", @@ -6489,12 +6490,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { "ext-pdo": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/app/src/Controller/User/RegisterUserAction.php b/app/src/Controller/User/RegisterUserAction.php index 005c3ea..b408c38 100644 --- a/app/src/Controller/User/RegisterUserAction.php +++ b/app/src/Controller/User/RegisterUserAction.php @@ -27,7 +27,6 @@ class RegisterUserAction extends Controller $success = $this->userRepository->create($user); if ($success) { - $this->session->delete("form_key"); return $this->render('user/success.twig'); } else { $this->session diff --git a/app/src/Middleware/FormKeyMiddleware.php b/app/src/Middleware/FormKeyMiddleware.php index ef822ea..ccc0e7e 100644 --- a/app/src/Middleware/FormKeyMiddleware.php +++ b/app/src/Middleware/FormKeyMiddleware.php @@ -3,6 +3,7 @@ namespace Slovocast\Middleware; use Odan\Session\SessionInterface; +use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface as RequestHandler; use Psr\Http\Message\ServerRequestInterface as Request; @@ -11,15 +12,18 @@ use Ramsey\Uuid\Uuid; class FormKeyMiddleware implements MiddlewareInterface { + const FORM_KEY = "form_key"; + public function __construct( - private SessionInterface $session + private SessionInterface $session, + private ResponseFactoryInterface $responseFactory ) { } public function process(Request $request, RequestHandler $handler): Response { - if (!$this->session->has("form_key")) { + if (!$this->session->has(self::FORM_KEY)) { $uuid = Uuid::uuid4(); - $this->session->set("form_key", $uuid->toString()); + $this->session->set(self::FORM_KEY, $uuid->toString()); } // check if the reuquest is a POST @@ -27,14 +31,17 @@ class FormKeyMiddleware implements MiddlewareInterface // return a 403 if the form key does not match if ($request->getMethod() === "POST") { $parsedBody = $request->getParsedBody(); - $sessionFormKey = $this->session->get('form_key'); + $sessionFormKey = $this->session->get(self::FORM_KEY); - if (isset($parsedBody['form_key'])) { - if ($parsedBody['form_key'] === $sessionFormKey) { - $this->session->delete('form_key'); + if (isset($parsedBody[self::FORM_KEY])) { + if ($parsedBody[self::FORM_KEY] === $sessionFormKey) { + $this->session->delete(self::FORM_KEY); return $handler->handle($request); } } + + $response = $this->responseFactory->createResponse(403, "Invalid Form Key"); + return $response; } return $handler->handle($request); diff --git a/app/src/Routes.php b/app/src/Routes.php index eb72594..25e67c9 100644 --- a/app/src/Routes.php +++ b/app/src/Routes.php @@ -11,6 +11,7 @@ use Slovocast\Controller\User\RegisterUserAction; use Slovocast\Controller\User\LoginUserPage; use Slovocast\Controller\User\LoginUserAction; use Slovocast\Controller\User\LogoutUserAction; +use Slovocast\Middleware\FormKeyMiddleware; use Slovocast\Middleware\VerifyPasswordMiddleware; use Slovocast\Middleware\AuthenticatedMiddleware; @@ -35,8 +36,10 @@ class Routes protected static function users(App $app): void { $app->get('/register', RegisterUserPage::class) + ->add(FormKeyMiddleware::class) ->setName('user-register-page'); $app->post('/register', RegisterUserAction::class) + ->add(FormKeyMiddleware::class) ->add(VerifyPasswordMiddleware::class) ->setName('user-register-action');