Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
CRAP | |
0.00% |
0 / 1 |
CsrfMiddleware | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 1 |
call | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | /** |
3 | * @section LICENSE |
4 | * This file is part of Wikimedia Slim application library |
5 | * |
6 | * Wikimedia Slim application library is free software: you can |
7 | * redistribute it and/or modify it under the terms of the GNU General Public |
8 | * License as published by the Free Software Foundation, either version 3 of |
9 | * the License, or (at your option) any later version. |
10 | * |
11 | * Wikimedia Slim application library is distributed in the hope that it |
12 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License along |
17 | * with Wikimedia Grants Review application. If not, see |
18 | * <http://www.gnu.org/licenses/>. |
19 | * |
20 | * @file |
21 | * @copyright © 2015 Bryan Davis, Wikimedia Foundation and contributors. |
22 | */ |
23 | |
24 | namespace Wikimedia\Slimapp; |
25 | |
26 | use Slim\Middleware; |
27 | |
28 | /** |
29 | * Middleware to manage Cross Site Request Forgery (CSRF) mitigation. |
30 | * |
31 | * Ensures that the user's session contains a random CSRF token. Verifies that |
32 | * HTTP requests using POST, PUT and DELETE verbs provide a parameter that |
33 | * matches the user's unique CSRF token. Exports 'csrf_param' and 'csrf_token' |
34 | * values to the view that can be used to generate appropriate form inputs. |
35 | * |
36 | * @author Bryan Davis <bd808@wikimedia.org> |
37 | * @copyright © 2015 Bryan Davis, Wikimedia Foundation and contributors. |
38 | */ |
39 | class CsrfMiddleware extends Middleware { |
40 | |
41 | private const PARAM = 'csrf_token'; |
42 | |
43 | /** |
44 | * Handle CSRF validation and view injection. |
45 | */ |
46 | public function call() { |
47 | if ( !isset( $_SESSION[self::PARAM] ) ) { |
48 | $_SESSION[self::PARAM] = sha1( session_id() . microtime() ); |
49 | } |
50 | |
51 | $token = $_SESSION[self::PARAM]; |
52 | $method = $this->app->request()->getMethod(); |
53 | |
54 | if ( in_array( $method, [ 'POST', 'PUT', 'DELETE' ] ) ) { |
55 | $requestToken = $this->app->request()->post( self::PARAM ); |
56 | if ( $token !== $requestToken ) { |
57 | $this->app->log->error( 'Missing or invalid CSRF token', [ |
58 | 'got' => $requestToken, |
59 | 'expected' => $token, |
60 | ] ); |
61 | $this->app->render( 'csrf.html', [], 400 ); |
62 | return; |
63 | } |
64 | } |
65 | |
66 | $this->app->view()->replace( [ |
67 | 'csrf_param' => self::PARAM, |
68 | 'csrf_token' => $token, |
69 | ] ); |
70 | |
71 | $this->next->call(); |
72 | } |
73 | |
74 | } |