11<?php
22namespace Slim \Extras \Middleware ;
33
4- /**
5- * CsrfGuard
6- *
7- * This middleware provides protection from CSRF attacks
8- * USAGE
9- *
10- * // Adding middleware
11- * $app = new Slim();
12- * $app->add(new CsrfGuard());
13- *
14- * // Setting token in view
15- * <input type="hidden" name="<?=$csrf_key?>" value="<?=$csrf_token?>">
16- *
17- * @author Mikhail Osher, https://github.com/miraage
18- * @version 1.0
19- */
204class CsrfGuard extends \Slim \Middleware
215{
226 /**
23- * Request key
24- *
25- * @var string
26- */
27- protected $ key ;
7+ * CSRF token key.
8+ *
9+ * @var string
10+ */
11+ protected $ key ;
2812
29- /**
30- * Constructor
31- *
32- * @param string $key Request key
33- */
34- public function __construct ( $ key = ' csrf_token ' )
35- {
36- // Validate key (i won't use htmlspecialchars)
37- if (!is_string ($ key ) || empty ($ key ) || preg_match ('/[^a-zA-Z0-9\-\_]/ ' , $ key )) {
38- throw new OutOfBoundsException ('Invalid key ' . $ key );
39- }
13+ /**
14+ * Constructor.
15+ *
16+ * @param string $key CSRF token key.
17+ * @return void
18+ */
19+ public function __construct ( $ key = ' csrf_token ' )
20+ {
21+ if (! is_string ($ key ) || empty ($ key ) || preg_match ('/[^a-zA-Z0-9\-\_]/ ' , $ key )) {
22+ throw new \ OutOfBoundsException ('Invalid CSRF token key " ' . $ key . ' " ' );
23+ }
4024
41- $ this ->key = $ key ;
42- }
25+ $ this ->key = $ key ;
26+ }
4327
44- /**
45- * Call middleware
46- */
47- public function call ()
48- {
49- // Attach as hook
50- $ this ->app ->hook ('slim.before ' , array ($ this , 'check ' ));
28+ /**
29+ * Call middleware.
30+ *
31+ * @return void
32+ */
33+ public function call ()
34+ {
35+ // Attach as hook.
36+ $ this ->app ->hook ('slim.before ' , array ($ this , 'check ' ));
5137
52- // Call next middleware
53- $ this ->next ->call ();
54- }
38+ // Call next middleware.
39+ $ this ->next ->call ();
40+ }
5541
56- /**
57- * Check token
58- */
59- public function check ()
60- {
61- // Create token
62- if (session_id () !== "" ) {
63- if (!isset ($ _SESSION [$ this ->key ])) {
64- $ _SESSION [$ this ->key ] = sha1 (serialize ($ _SERVER ) . rand (0 , 0xffffffff ));
65- }
66- } else {
67- throw new Exception ( "Session are required to use CSRF Guard " );
68- }
69- $ token = $ _SESSION [$ this ->key ];
42+ /**
43+ * Check CSRF token is valid.
44+ * Note: Also checks POST data to see if a Moneris RVAR CSRF token exists.
45+ *
46+ * @return void
47+ */
48+ public function check () {
49+ // Check sessions are enabled.
50+ if (session_id () === '' ) {
51+ throw new \Exception ('Sessions are required to use the CSRF Guard middleware. ' );
52+ }
53+
54+ if (! isset ($ _SESSION [$ this ->key ])) {
55+ $ _SESSION [$ this ->key ] = sha1 (serialize ($ _SERVER ) . rand (0 , 0xffffffff ));
56+ }
57+
58+ $ token = $ _SESSION [$ this ->key ];
7059
71- // Validate
72- if (in_array ($ this ->app ->request ()->getMethod (), array ('POST ' , 'PUT ' , 'DELETE ' ))) {
73- $ usertoken = $ this ->app ->request ()->post ($ this ->key );
74- if ($ token !== $ usertoken ) {
75- $ this -> app -> halt ( 400 , ' Missing token ' );
60+ // Validate the CSRF token.
61+ if (in_array ($ this ->app ->request ()->getMethod (), array ('POST ' , 'PUT ' , 'DELETE ' ))) {
62+ $ userToken = $ this ->app ->request ()->post ($ this ->key );
63+ if ($ token !== $ userToken ) {
64+ session_destroy ( );
7665 }
77- }
66+ }
7867
79- // Assign to view
80- $ this ->app ->view ()->appendData (array (
81- 'csrf_key ' => $ this ->key ,
82- 'csrf_token ' => $ token ,
83- ));
84- }
85- }
68+ // Assign CSRF token key and value to view.
69+ $ this ->app ->view ()->appendData (array (
70+ 'csrf_key ' => $ this ->key ,
71+ 'csrf_token ' => $ token ,
72+ ));
73+ }
74+ }
0 commit comments