summaryrefslogtreecommitdiff
path: root/src/Middleware
diff options
context:
space:
mode:
authorIgor Scheller <igor.scheller@igorshp.de>2018-09-03 15:33:13 +0100
committermsquare <msquare@notrademark.de>2018-11-21 19:24:36 +0100
commit23c0fae36fb8159bcf8b95bae98555201146457e (patch)
tree6a169114a47391adb1da701f630bb27d73e925d2 /src/Middleware
parent8236989be066c51c5f57884bcc42dbc387794651 (diff)
Added csrf middleware
Diffstat (limited to 'src/Middleware')
-rw-r--r--src/Middleware/VerifyCsrfToken.php90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/Middleware/VerifyCsrfToken.php b/src/Middleware/VerifyCsrfToken.php
new file mode 100644
index 00000000..cc0c1fbc
--- /dev/null
+++ b/src/Middleware/VerifyCsrfToken.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
+
+class VerifyCsrfToken implements MiddlewareInterface
+{
+ /** @var SessionInterface */
+ protected $session;
+
+ /**
+ * @param SessionInterface $session
+ */
+ public function __construct(SessionInterface $session)
+ {
+ $this->session = $session;
+ }
+
+ /**
+ * Verify csrf tokens
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ * @return ResponseInterface
+ */
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ {
+ if (
+ $this->isReading($request)
+ || $this->tokensMatch($request)
+ ) {
+ return $handler->handle($request);
+ }
+
+ return $this->notAuthorizedResponse();
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ * @return bool
+ */
+ protected function isReading(ServerRequestInterface $request): bool
+ {
+ return in_array(
+ $request->getMethod(),
+ ['GET', 'HEAD', 'OPTIONS']
+ );
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ * @return bool
+ */
+ protected function tokensMatch(ServerRequestInterface $request): bool
+ {
+ $token = null;
+ $body = $request->getParsedBody();
+ $header = $request->getHeader('X-CSRF-TOKEN');
+
+ if (is_array($body) && isset($body['_token'])) {
+ $token = $body['_token'];
+ }
+
+ if (!empty($header)) {
+ $header = array_shift($header);
+ }
+
+ $token = $token ?: $header;
+ $sessionToken = $this->session->get('_token');
+
+ return is_string($token)
+ && is_string($sessionToken)
+ && hash_equals($sessionToken, $token);
+ }
+
+ /**
+ * @return ResponseInterface
+ * @codeCoverageIgnore
+ */
+ protected function notAuthorizedResponse(): ResponseInterface
+ {
+ // The 419 code is used as "Page Expired" to differentiate from a 401 (not authorized)
+ return response()->withStatus(419, 'Authentication Token Mismatch');
+ }
+}