diff --git a/composer.json b/composer.json index e7d8f0c8..06a0ccb5 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "php": ">=8.1", "phpgt/config": "^1.0", + "phpgt/csrf": "^v1.9", "phpgt/dom": "^v4.0", "phpgt/domtemplate": "^v3.1", "phpgt/database": "^1.4", diff --git a/composer.lock b/composer.lock index 2a8d5ff6..be24cec9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "02bb7a1a0399a9fead5c9d21273eb29b", + "content-hash": "b1fb79f4fc1286b820e47716f4085ff7", "packages": [ { "name": "magicalex/write-ini-file", @@ -171,6 +171,64 @@ ], "time": "2021-01-30T14:24:07+00:00" }, + { + "name": "phpgt/csrf", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/PhpGt/Csrf.git", + "reference": "30d67a65466976c90e94c571834d041cc4d8fb5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PhpGt/Csrf/zipball/30d67a65466976c90e94c571834d041cc4d8fb5e", + "reference": "30d67a65466976c90e94c571834d041cc4d8fb5e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "phpgt/dom": "^v4.0", + "phpgt/session": "^v1.1" + }, + "require-dev": { + "phpstan/phpstan": "^v1.8", + "phpunit/phpunit": "^v9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gt\\Csrf\\": "./src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Fellows", + "email": "mrfellows@gmail.com", + "role": "Developer" + }, + { + "name": "Greg Bowler", + "email": "greg.bowler@g105b.com", + "role": "Developer" + } + ], + "description": "Automatic protection from Cross-Site Request Forgery.", + "support": { + "issues": "https://github.com/PhpGt/Csrf/issues", + "source": "https://github.com/PhpGt/Csrf/tree/v1.9.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/PhpGt", + "type": "github" + } + ], + "time": "2022-09-23T12:03:51+00:00" + }, { "name": "phpgt/cssxpath", "version": "v1.1.4", @@ -939,24 +997,24 @@ }, { "name": "phpgt/ulid", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/PhpGt/Ulid.git", - "reference": "17edd130b29fc4ca70d457d9758ac6208ceaa6ab" + "reference": "6fdbf83672c98013d530d2fb469768602b505aff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PhpGt/Ulid/zipball/17edd130b29fc4ca70d457d9758ac6208ceaa6ab", - "reference": "17edd130b29fc4ca70d457d9758ac6208ceaa6ab", + "url": "https://api.github.com/repos/PhpGt/Ulid/zipball/6fdbf83672c98013d530d2fb469768602b505aff", + "reference": "6fdbf83672c98013d530d2fb469768602b505aff", "shasum": "" }, "require": { "php": ">=8.0" }, "require-dev": { - "phpstan/phpstan": "v1.8.0", - "phpunit/phpunit": "v9.5.21" + "phpstan/phpstan": "^v1.8", + "phpunit/phpunit": "^v9.5" }, "type": "library", "autoload": { @@ -979,7 +1037,7 @@ "description": "Unique, lexicographically sortable identifiers.", "support": { "issues": "https://github.com/PhpGt/Ulid/issues", - "source": "https://github.com/PhpGt/Ulid/tree/v1.1.0" + "source": "https://github.com/PhpGt/Ulid/tree/v1.1.1" }, "funding": [ { @@ -987,7 +1045,7 @@ "type": "github" } ], - "time": "2022-07-30T19:02:35+00:00" + "time": "2022-09-24T17:38:47+00:00" }, { "name": "psr/container", @@ -1557,16 +1615,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -1607,9 +1665,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" }, - "time": "2022-05-31T20:59:12+00:00" + "time": "2022-09-04T07:30:47+00:00" }, { "name": "phar-io/manifest", @@ -2010,23 +2068,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.15", + "version": "9.2.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", + "nikic/php-parser": "^4.14", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -2075,7 +2133,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" }, "funding": [ { @@ -2083,7 +2141,7 @@ "type": "github" } ], - "time": "2022-03-07T09:28:20+00:00" + "time": "2022-08-30T12:24:04+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2597,16 +2655,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -2659,7 +2717,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -2667,7 +2725,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -2857,16 +2915,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -2922,7 +2980,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -2930,7 +2988,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -3285,16 +3343,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", "shasum": "" }, "require": { @@ -3306,7 +3364,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3329,7 +3387,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" }, "funding": [ { @@ -3337,7 +3395,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2022-09-12T14:47:03+00:00" }, { "name": "sebastian/version", @@ -3455,5 +3513,5 @@ "php": ">=8.1" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } diff --git a/src/Middleware/RequestHandler.php b/src/Middleware/RequestHandler.php index b23a1ff9..26fd8cee 100644 --- a/src/Middleware/RequestHandler.php +++ b/src/Middleware/RequestHandler.php @@ -4,6 +4,8 @@ use Gt\Config\Config; use Gt\Config\ConfigFactory; use Gt\Config\ConfigSection; +use Gt\Csrf\HTMLDocumentProtector; +use Gt\Csrf\SessionTokenStore; use Gt\Dom\HTMLDocument; use Gt\DomTemplate\ComponentExpander; use Gt\DomTemplate\DocumentBinder; @@ -183,7 +185,6 @@ public function handle( $viewModel->body->classList->add($bodyDirClass); } -// ini_set('session.serialize_handler', 'php_serialize'); $sessionConfig = $this->config->getSection("session"); $sessionId = $_COOKIE[$sessionConfig["name"]] ?? null; $sessionHandler = SessionSetup::attachHandler( @@ -196,17 +197,18 @@ public function handle( ); $serviceContainer->set($session); -// TODO: Complete CSRF implementation - maybe use its own cookie? -// /** @var Session $session */ -// $session = $serviceContainer->get(Session::class); -// $csrfTokenStore = new SessionTokenStore($session->getStore("csrf", true)); -// -// if($request->getMethod() === "POST") { -// $csrfTokenStore->processAndVerify($_POST); -// } -// -// $protector = new HTMLDocumentProtector($viewModel, $csrfTokenStore); -// $protector->protectAndInject(); + $session = $serviceContainer->get(Session::class); + $csrfTokenStore = new SessionTokenStore( + $session->getStore("csrf", true) + ); + + if($request->getMethod() === "POST") { + $csrfTokenStore->verify($_POST); + } + + $protector = new HTMLDocumentProtector($viewModel, $csrfTokenStore); + $tokens = $protector->protect(HTMLDocumentProtector::ONE_TOKEN_PER_FORM); + $response = $response->withHeader("x-csrf", $tokens); } // TODO: Kill globals.