xref: /webtrees/app/Http/Middleware/CheckCsrf.php (revision e873f434551745f888937263ff89e80db3b0f785)
1ccb0284cSGreg Roach<?php
23976b470SGreg Roach
3ccb0284cSGreg Roach/**
4ccb0284cSGreg Roach * webtrees: online genealogy
5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team
6ccb0284cSGreg Roach * This program is free software: you can redistribute it and/or modify
7ccb0284cSGreg Roach * it under the terms of the GNU General Public License as published by
8ccb0284cSGreg Roach * the Free Software Foundation, either version 3 of the License, or
9ccb0284cSGreg Roach * (at your option) any later version.
10ccb0284cSGreg Roach * This program is distributed in the hope that it will be useful,
11ccb0284cSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12ccb0284cSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13ccb0284cSGreg Roach * GNU General Public License for more details.
14ccb0284cSGreg Roach * You should have received a copy of the GNU General Public License
1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
16ccb0284cSGreg Roach */
17fcfa147eSGreg Roach
18ccb0284cSGreg Roachdeclare(strict_types=1);
19ccb0284cSGreg Roach
20ccb0284cSGreg Roachnamespace Fisharebest\Webtrees\Http\Middleware;
21ccb0284cSGreg Roach
226ccdf4f0SGreg Roachuse Fig\Http\Message\RequestMethodInterface;
23094bd4e5SGreg Roachuse Fisharebest\Webtrees\FlashMessages;
24901ade19SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\Logout;
25901ade19SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\SelectLanguage;
26901ade19SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\SelectTheme;
27ccb0284cSGreg Roachuse Fisharebest\Webtrees\I18N;
28ccb0284cSGreg Roachuse Fisharebest\Webtrees\Session;
29b55cbc6bSGreg Roachuse Fisharebest\Webtrees\Validator;
306ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface;
316ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
326ccdf4f0SGreg Roachuse Psr\Http\Server\MiddlewareInterface;
336ccdf4f0SGreg Roachuse Psr\Http\Server\RequestHandlerInterface;
343976b470SGreg Roach
35ba8e6c18SGreg Roachuse function in_array;
36ccb0284cSGreg Roach
37ccb0284cSGreg Roach/**
38ccb0284cSGreg Roach * Middleware to wrap a request in a transaction.
39ccb0284cSGreg Roach */
40c1010edaSGreg Roachclass CheckCsrf implements MiddlewareInterface
41c1010edaSGreg Roach{
42*e873f434SGreg Roach    private const array EXCLUDE_ROUTES = [
43901ade19SGreg Roach        Logout::class,
44901ade19SGreg Roach        SelectLanguage::class,
45901ade19SGreg Roach        SelectTheme::class,
46ba8e6c18SGreg Roach    ];
47ba8e6c18SGreg Roach
48ccb0284cSGreg Roach    /**
496ccdf4f0SGreg Roach     * @param ServerRequestInterface  $request
506ccdf4f0SGreg Roach     * @param RequestHandlerInterface $handler
51ccb0284cSGreg Roach     *
526ccdf4f0SGreg Roach     * @return ResponseInterface
53ccb0284cSGreg Roach     */
546ccdf4f0SGreg Roach    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
55c1010edaSGreg Roach    {
566ccdf4f0SGreg Roach        if ($request->getMethod() === RequestMethodInterface::METHOD_POST) {
57b55cbc6bSGreg Roach            $route = Validator::attributes($request)->route();
58f307429bSGreg Roach
59f307429bSGreg Roach            if (!in_array($route->name, self::EXCLUDE_ROUTES, true)) {
60b46c87bdSGreg Roach                $params        = (array) $request->getParsedBody();
61e240f5e1SGreg Roach                $client_token  = $params['_csrf'] ?? $request->getHeaderLine('X-CSRF-TOKEN');
62ccb0284cSGreg Roach                $session_token = Session::get('CSRF_TOKEN');
63ccb0284cSGreg Roach
64f307429bSGreg Roach                unset($params['_csrf']);
65f307429bSGreg Roach
66f307429bSGreg Roach                $request = $request->withParsedBody($params);
67f307429bSGreg Roach
68310b7a5aSGreg Roach                if ($client_token !== $session_token) {
6981443e3cSGreg Roach                    if ($client_token === '') {
702ba27980SGreg Roach                        FlashMessages::addMessage(I18N::translate('The form data is incomplete. Perhaps you need to increase max_input_vars on your server?'));
7181443e3cSGreg Roach                    } else {
72094bd4e5SGreg Roach                        FlashMessages::addMessage(I18N::translate('This form has expired. Try again.'));
7381443e3cSGreg Roach                    }
74094bd4e5SGreg Roach
75f567c3d8SGreg Roach                    return redirect((string) $request->getUri());
76ccb0284cSGreg Roach                }
77310b7a5aSGreg Roach            }
78310b7a5aSGreg Roach        }
79ccb0284cSGreg Roach
806ccdf4f0SGreg Roach        return $handler->handle($request);
81ccb0284cSGreg Roach    }
82ccb0284cSGreg Roach}
83