Skip to content

Commit 1d7121c

Browse files
committed
Merge pull request #32 from ziadoz/patch-3
Destroy session when CSRF check fails.
2 parents 271d528 + 73c5962 commit 1d7121c

File tree

1 file changed

+72
-70
lines changed

1 file changed

+72
-70
lines changed

Middleware/CsrfGuard.php

Lines changed: 72 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,87 @@
11
<?php
22
namespace 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-
*/
204
class CsrfGuard extends \Slim\Middleware
215
{
226
/**
23-
* Request key
24-
*
25-
* @var string
26-
*/
27-
protected $key;
7+
* CSRF token key name.
8+
*
9+
* @var string
10+
*/
11+
protected $key;
2812

2913
/**
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-
}
14+
* CSRF graceful.
15+
*
16+
* @var string
17+
*/
18+
protected $graceful;
4019

41-
$this->key = $key;
42-
}
20+
/**
21+
* Constructor.
22+
*
23+
* @param boolean $graceful If true then destroy the session (graceful), otherwise halt the application (ungraceful).
24+
* @param string $key The CSRF token key name.
25+
* @return void
26+
*/
27+
public function __construct($graceful = false, $key = 'csrf_token')
28+
{
29+
if (! is_string($key) || empty($key) || preg_match('/[^a-zA-Z0-9\-\_]/', $key)) {
30+
throw new \OutOfBoundsException('Invalid CSRF token key "' . $key . '"');
31+
}
4332

44-
/**
45-
* Call middleware
46-
*/
47-
public function call()
48-
{
49-
// Attach as hook
50-
$this->app->hook('slim.before', array($this, 'check'));
33+
$this->key = $key;
34+
$this->graceful = (bool) $graceful;
35+
}
5136

52-
// Call next middleware
53-
$this->next->call();
54-
}
37+
/**
38+
* Call middleware.
39+
*
40+
* @return void
41+
*/
42+
public function call()
43+
{
44+
// Attach as hook.
45+
$this->app->hook('slim.before', array($this, 'check'));
5546

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];
47+
// Call next middleware.
48+
$this->next->call();
49+
}
50+
51+
/**
52+
* Check CSRF token is valid.
53+
* Note: Also checks POST data to see if a Moneris RVAR CSRF token exists.
54+
*
55+
* @return void
56+
*/
57+
public function check() {
58+
// Check sessions are enabled.
59+
if (session_id() === '') {
60+
throw new \Exception('Sessions are required to use the CSRF Guard middleware.');
61+
}
62+
63+
if (! isset($_SESSION[$this->key])) {
64+
$_SESSION[$this->key] = sha1(serialize($_SERVER) . rand(0, 0xffffffff));
65+
}
66+
67+
$token = $_SESSION[$this->key];
7068

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');
69+
// Validate the CSRF token.
70+
if (in_array($this->app->request()->getMethod(), array('POST', 'PUT', 'DELETE'))) {
71+
$userToken = $this->app->request()->post($this->key);
72+
if ($token !== $userToken) {
73+
if (! $this->graceful) {
74+
$this->app->halt(400, 'Invalid or missing CSRF token.');
75+
} else {
76+
session_destroy();
77+
}
7678
}
77-
}
79+
}
7880

79-
// Assign to view
80-
$this->app->view()->appendData(array(
81-
'csrf_key' => $this->key,
82-
'csrf_token' => $token,
83-
));
84-
}
85-
}
81+
// Assign CSRF token key and value to view.
82+
$this->app->view()->appendData(array(
83+
'csrf_key' => $this->key,
84+
'csrf_token' => $token,
85+
));
86+
}
87+
}

0 commit comments

Comments
 (0)