From 27c3cad28785990589846b7306c405481d501c7d Mon Sep 17 00:00:00 2001 From: Alwin Drenth Date: Tue, 13 Jul 2021 11:48:47 +0200 Subject: [PATCH] Drop PHP 7.1 support --- .github/workflows/php.yml | 2 +- Plugin.php | 33 ++------- README.md | 22 ++---- ...ServiceProvider.php => ServiceProvider.php | 17 +---- composer.json | 2 +- config.php | 2 +- middleware/VerifyCsrfTokenMiddleware.php | 67 +++++-------------- updates/version.yaml | 1 + 8 files changed, 33 insertions(+), 113 deletions(-) rename serviceproviders/CsrfServiceProvider.php => ServiceProvider.php (79%) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index f310a42..b1c4618 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: true matrix: - php: [ 8.0, 7.4, 7.3, 7.2, 7.1 ] + php: [ 8.0, 7.4 ] stability: [ prefer-lowest, prefer-stable ] name: PHP ${{ matrix.php }} - ${{ matrix.stability }} diff --git a/Plugin.php b/Plugin.php index b94d0c2..7b1d540 100644 --- a/Plugin.php +++ b/Plugin.php @@ -1,27 +1,15 @@ middleware(Middleware\VerifyCsrfTokenMiddleware::class); + CmsController::extend(static function (CmsController $controller): void { + $controller->middleware(VerifyCsrfTokenMiddleware::class); }); } - /** - * {@inheritDoc} - */ public function register(): void { - $this->app->register(ServiceProviders\CsrfServiceProvider::class); + $this->app->register(ServiceProvider::class); } - /** - * {@inheritDoc} - */ public function registerMarkupTags(): array { return [ 'functions' => [ - 'csrf_token' => static function () { + 'csrf_token' => static function (): string { return csrf_token(); }, ], diff --git a/README.md b/README.md index b4b0ef6..6f31d69 100644 --- a/README.md +++ b/README.md @@ -4,35 +4,23 @@ Adds CSRF protection. ## Requirements -* PHP 7.1 or higher +* PHP 7.4 or higher ## Installation -*Composer:* - ``` composer require vdlp/oc-csrf-plugin ``` -*CLI:* - -``` -php artisan plugin:install Vdlp.Csrf -``` - -*October CMS:* - -Go to Settings > Updates & Plugins > Install plugins and search for 'CSRF'. - ## Configuration -Add the plugin configuration to your projects' config folder: +Add the plugin configuration to your config folder: ``` -php artisan vendor:publish --provider="Vdlp\Csrf\ServiceProviders\CsrfServiceProvider" --tag="config" +php artisan vendor:publish --provider="Vdlp\Csrf\ServiceProvider" --tag="config" ``` -Add the CSRF token to the head: +Add the CSRF token to the `` section: ``` @@ -52,4 +40,4 @@ $.ajaxSetup({ ## Questions? Need help? -If you have any question about how to use this plugin, please don't hesitate to contact us at octobercms@vdlp.nl. We're happy to help you. You can also visit the support forum and drop your questions/issues there. +If you have any question about how to use this plugin, please don't hesitate to contact us at octobercms@vdlp.nl. We're happy to help you. diff --git a/serviceproviders/CsrfServiceProvider.php b/ServiceProvider.php similarity index 79% rename from serviceproviders/CsrfServiceProvider.php rename to ServiceProvider.php index ace694d..4a2cb3b 100644 --- a/serviceproviders/CsrfServiceProvider.php +++ b/ServiceProvider.php @@ -2,25 +2,17 @@ declare(strict_types=1); -namespace Vdlp\Csrf\ServiceProviders; +namespace Vdlp\Csrf; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Encryption\Encrypter; use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Routing\Redirector; -use October\Rain\Support\ServiceProvider; +use October\Rain\Support\ServiceProvider as ServiceProviderBase; use Vdlp\Csrf\Middleware\VerifyCsrfTokenMiddleware; -/** - * Class CsrfServiceProvider - * - * @package Vdlp\Csrf\ServiceProviders - */ -final class CsrfServiceProvider extends ServiceProvider +final class ServiceProvider extends ServiceProviderBase { - /** - * @return void - */ public function boot(): void { $this->publishes([ @@ -28,9 +20,6 @@ public function boot(): void ], 'config'); } - /** - * @return void - */ public function register(): void { $this->app->bind( diff --git a/composer.json b/composer.json index a11dd78..10114d4 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": "^7.1||^8.0", + "php": "^7.4 || ^8.0", "composer/installers": "^1.0" } } diff --git a/config.php b/config.php index 45c6fc8..c426416 100644 --- a/config.php +++ b/config.php @@ -14,7 +14,7 @@ */ 'exclude_paths' => [ - // i.e. '/path/to/exclude' + // Example: '/path/to/exclude' ], ]; diff --git a/middleware/VerifyCsrfTokenMiddleware.php b/middleware/VerifyCsrfTokenMiddleware.php index 94caf4a..78f071c 100644 --- a/middleware/VerifyCsrfTokenMiddleware.php +++ b/middleware/VerifyCsrfTokenMiddleware.php @@ -5,49 +5,22 @@ namespace Vdlp\Csrf\Middleware; use Closure; +use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Contracts\Encryption\Encrypter; use Illuminate\Contracts\Routing\ResponseFactory; -use Illuminate\Http\JsonResponse; -use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Routing\Redirector; use October\Rain\Cookie\Middleware\EncryptCookies; use RuntimeException; use Throwable; -/** - * Class VerifyCsrfTokenMiddleware - * - * @package Vdlp\Csrf\Middleware - */ final class VerifyCsrfTokenMiddleware { - /** - * @var Encrypter - */ - private $encrypter; - - /** - * @var Redirector - */ - private $redirector; - - /** - * @var ResponseFactory - */ - private $responseFactory; - - /** - * @var array - */ - private $excludePaths; + private Encrypter $encrypter; + private Redirector $redirector; + private ResponseFactory $responseFactory; + private array $excludePaths; - /** - * @param Encrypter $encrypter - * @param Redirector $redirector - * @param ResponseFactory $responseFactory - * @param array $excludePaths - */ public function __construct( Encrypter $encrypter, Redirector $redirector, @@ -61,9 +34,7 @@ public function __construct( } /** - * @param Request $request - * @param Closure $next - * @return RedirectResponse|JsonResponse + * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|mixed * @throws RuntimeException */ public function handle(Request $request, Closure $next) @@ -81,47 +52,39 @@ public function handle(Request $request, Closure $next) return $this->redirector->refresh(); } - /** - * @param Request $request - * @return bool - */ - private function isReading($request): bool + private function isReading(Request $request): bool { - return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']); + return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS'], true); } /** - * @param Request $request - * @return bool * @throws RuntimeException */ private function tokensMatch(Request $request): bool { $token = $this->getTokenFromRequest($request); - return is_string($request->session()->token()) - && is_string($token) + /** @var mixed $sessionToken */ + $sessionToken = $request->session()->token(); + + return is_string($sessionToken) && hash_equals($request->session()->token(), $token); } - /** - * @param Request $request - * @return bool - */ private function excludePathMatch(Request $request): bool { return in_array($request->path(), $this->excludePaths, true); } /** - * @param Request $request - * @return string + * @throws DecryptException */ private function getTokenFromRequest(Request $request): string { $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN'); + $header = $request->header('X-XSRF-TOKEN'); - if (!$token && $header = $request->header('X-XSRF-TOKEN')) { + if (($token === null || $token === '') && is_string($header)) { $token = $this->encrypter->decrypt($header, EncryptCookies::serialized('XSRF-TOKEN')); } diff --git a/updates/version.yaml b/updates/version.yaml index 627210b..266a011 100644 --- a/updates/version.yaml +++ b/updates/version.yaml @@ -2,3 +2,4 @@ 1.1.0: "Added configuration to exclude paths from CSRF validation -- See: https://github.com/vdlp/oc-csrf-plugin/releases/tag/1.1.0" 1.1.1: "Prevent error on CSRF token conversion -- See: https://github.com/vdlp/oc-csrf-plugin/releases/tag/1.1.1" 1.1.2: "Update plugin dependencies" +2.0.0: "Support for PHP 7.4 or higher"