From 6c6d81d3c9fdb320daca0643f869a3cce4ef8c18 Mon Sep 17 00:00:00 2001 From: sessingo Date: Thu, 6 Apr 2023 13:09:26 +0200 Subject: [PATCH 1/4] [!!!] CsrfVerifier changes - [!!!] Made $except and $include array not nullable. - Added more customizable BaseCsrfVerifier. Can now be used as ticket for no hotlinking etc. --- .../Http/Middleware/BaseCsrfVerifier.php | 43 +++++++++++-------- .../Dummy/CsrfVerifier/DummyCsrfVerifier.php | 4 +- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php index 454c6cd..7d26945 100644 --- a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php +++ b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php @@ -17,13 +17,13 @@ class BaseCsrfVerifier implements IMiddleware * For example: /admin/* * @var array|null */ - protected ?array $except = null; + protected array $except = []; /** * Urls to include. Can be used to include urls from a certain path. * @var array|null */ - protected ?array $include = null; + protected array $include = []; /** * @var ITokenProvider @@ -38,6 +38,23 @@ class BaseCsrfVerifier implements IMiddleware $this->tokenProvider = new CookieTokenProvider(); } + protected function isIncluded(Request $request): bool + { + if (count($this->include) > 0) { + foreach ($this->include as $includeUrl) { + $includeUrl = rtrim($includeUrl, '/'); + if ($includeUrl[strlen($includeUrl) - 1] === '*') { + $includeUrl = rtrim($includeUrl, '*'); + return $request->getUrl()->contains($includeUrl); + } + + return ($includeUrl === rtrim($request->getUrl()->getRelativeUrl(false), '/')); + } + } + + return false; + } + /** * Check if the url matches the urls in the except property * @param Request $request @@ -45,11 +62,11 @@ class BaseCsrfVerifier implements IMiddleware */ protected function skip(Request $request): bool { - if ($this->except === null || count($this->except) === 0) { + if (count($this->except) === 0) { return false; } - foreach($this->except as $url) { + foreach ($this->except as $url) { $url = rtrim($url, '/'); if ($url[strlen($url) - 1] === '*') { $url = rtrim($url, '*'); @@ -60,20 +77,9 @@ class BaseCsrfVerifier implements IMiddleware if ($skip === true) { - if(is_array($this->include) === true && count($this->include) > 0) { - foreach($this->include as $includeUrl) { - $includeUrl = rtrim($includeUrl, '/'); - if ($includeUrl[strlen($includeUrl) - 1] === '*') { - $includeUrl = rtrim($includeUrl, '*'); - $skip = !$request->getUrl()->contains($includeUrl); - break; - } + $skip = !$this->isIncluded($request); - $skip = !($includeUrl === rtrim($request->getUrl()->getRelativeUrl(false), '/')); - } - } - - if($skip === false) { + if ($skip === false) { continue; } @@ -92,12 +98,11 @@ class BaseCsrfVerifier implements IMiddleware */ public function handle(Request $request): void { - if ($this->skip($request) === false && $request->isPostBack() === true) { + if ($this->skip($request) === false && ($request->isPostBack() === true || $this->isIncluded($request) === true)) { $token = $request->getInputHandler()->value( static::POST_KEY, $request->getHeader(static::HEADER_KEY), - Request::$requestTypesPost ); if ($this->tokenProvider->validate((string)$token) === false) { diff --git a/tests/Pecee/SimpleRouter/Dummy/CsrfVerifier/DummyCsrfVerifier.php b/tests/Pecee/SimpleRouter/Dummy/CsrfVerifier/DummyCsrfVerifier.php index 4c87c37..8e3b5e1 100644 --- a/tests/Pecee/SimpleRouter/Dummy/CsrfVerifier/DummyCsrfVerifier.php +++ b/tests/Pecee/SimpleRouter/Dummy/CsrfVerifier/DummyCsrfVerifier.php @@ -2,12 +2,12 @@ class DummyCsrfVerifier extends \Pecee\Http\Middleware\BaseCsrfVerifier { - protected ?array $except = [ + protected array $except = [ '/exclude-page', '/exclude-all/*', ]; - protected ?array $include = [ + protected array $include = [ '/exclude-all/include-page', ]; From aa654a3ac6b23c82326aea9891c9e975553654fd Mon Sep 17 00:00:00 2001 From: sessingo Date: Fri, 7 Apr 2023 13:05:27 +0200 Subject: [PATCH 2/4] [BUGFIX] Fixed exception-handler rewrite not always triggered --- src/Pecee/SimpleRouter/Router.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index a066b77..c00c8d5 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -346,7 +346,7 @@ class Router /* Verify csrf token for request */ $this->csrfVerifier->handle($this->request); } catch(Exception $e) { - $this->handleException($e); + return $this->handleException($e); } } @@ -444,12 +444,12 @@ class Router } } catch (Exception $e) { - $this->handleException($e); + return $this->handleException($e); } if ($methodNotAllowed === true) { $message = sprintf('Route "%s" or method "%s" not allowed.', $this->request->getUrl()->getPath(), $this->request->getMethod()); - $this->handleException(new NotFoundHttpException($message, 403)); + return $this->handleException(new NotFoundHttpException($message, 403)); } if (count($this->request->getLoadedRoutes()) === 0) { From 791d69b24de7b17c2c740680cfa1809f18138b9e Mon Sep 17 00:00:00 2001 From: sessingo Date: Fri, 7 Apr 2023 13:08:40 +0200 Subject: [PATCH 3/4] Updated documentation --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index cc3666e..3a50b96 100644 --- a/README.md +++ b/README.md @@ -1036,6 +1036,17 @@ class CustomExceptionHandler implements IExceptionHandler return; } + + /* Other error */ + if($error instanceof MyCustomException) { + + $request->setRewriteRoute( + // Add new route based on current url (minus query-string) and add custom parameters. + (new RouteUrl(url(null, null, []), 'PageController@error'))->setParameters(['exception' => $error]) + ); + return; + + } throw $error; From d6642a7f7ba52ece6c6ae108cc1d858e037f65cb Mon Sep 17 00:00:00 2001 From: sessingo Date: Fri, 7 Apr 2023 15:30:24 +0200 Subject: [PATCH 4/4] Changed behavior of router to always exspect returned output to be string. --- src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php | 12 ++++++------ src/Pecee/SimpleRouter/Router.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php index 77c9978..82e18ee 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php @@ -27,11 +27,11 @@ class ClassLoader implements IClassLoader * @param object $class * @param string $method * @param array $parameters - * @return mixed + * @return string */ - public function loadClassMethod($class, string $method, array $parameters) + public function loadClassMethod($class, string $method, array $parameters): string { - return call_user_func_array([$class, $method], array_values($parameters)); + return (string)call_user_func_array([$class, $method], array_values($parameters)); } /** @@ -39,11 +39,11 @@ class ClassLoader implements IClassLoader * * @param Callable $closure * @param array $parameters - * @return mixed + * @return string */ - public function loadClosure(Callable $closure, array $parameters) + public function loadClosure(callable $closure, array $parameters): string { - return call_user_func_array($closure, array_values($parameters)); + return (string)call_user_func_array($closure, array_values($parameters)); } } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index c00c8d5..ff12732 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -427,7 +427,7 @@ class Router $routeOutput = $route->renderRoute($this->request, $this); if ($this->renderMultipleRoutes === true) { - if ($routeOutput !== null) { + if ($routeOutput !== '') { return $routeOutput; }