Skip to content

Commit 88cfff1

Browse files
authored
Merge pull request #88 from mebjas/dev-master-issue80
Fix to issue #80
2 parents 756129f + 5fda1dc commit 88cfff1

File tree

3 files changed

+78
-20
lines changed

3 files changed

+78
-20
lines changed

js/csrfprotector.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,8 @@ function csrfprotector_init() {
289289
*/
290290
function new_send(data) {
291291
if (this.method.toLowerCase() === 'post') {
292-
if (data !== null && typeof data === 'object') {
293-
data.append(CSRFP.CSRFP_TOKEN, CSRFP._getAuthKey());
294-
} else {
295-
if (typeof data != "undefined") {
296-
data += "&";
297-
} else {
298-
data = "";
299-
}
300-
data += CSRFP.CSRFP_TOKEN +"=" +CSRFP._getAuthKey();
301-
}
292+
// attach the token in request header
293+
this.setRequestHeader(CSRFP.CSRFP_TOKEN, CSRFP._getAuthKey());
302294
}
303295
return this.old_send(data);
304296
}

libs/csrf/csrfprotector.php

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<?php
2-
32
if (!defined('__CSRF_PROTECTOR__')) {
43
define('__CSRF_PROTECTOR__', true); // to avoid multiple declaration errors
54

@@ -90,10 +89,17 @@ class csrfProtector
9089
/**
9190
* Variable: $cookieConfig
9291
* Array of parameters for the setcookie method
93-
* @var cookieConfig;
92+
* @var array<any>
9493
*/
9594
private static $cookieConfig = null;
9695

96+
/**
97+
* Variable: $tokenHeaderKey
98+
* Key value in header array, which contain the token
99+
* @var string
100+
*/
101+
private static $tokenHeaderKey = null;
102+
97103
/*
98104
* Variable: $requestType
99105
* Varaible to store weather request type is post or get
@@ -188,6 +194,9 @@ public static function init($length = null, $action = null)
188194
if (self::$config['CSRFP_TOKEN'] == '')
189195
self::$config['CSRFP_TOKEN'] = CSRFP_TOKEN;
190196

197+
self::$tokenHeaderKey = 'HTTP_' .strtoupper(self::$config['CSRFP_TOKEN']);
198+
self::$tokenHeaderKey = str_replace('-', '_', self::$tokenHeaderKey);
199+
191200
// load parameters for setcookie method
192201
if (!isset(self::$config['cookieConfig']))
193202
self::$config['cookieConfig'] = array();
@@ -248,19 +257,19 @@ public static function authorizePost()
248257
//set request type to POST
249258
self::$requestType = "POST";
250259

260+
// look for token in payload else from header
261+
$token = self::getTokenFromRequest();
262+
251263
//currently for same origin only
252-
if (!(isset($_POST[self::$config['CSRFP_TOKEN']])
253-
&& isset($_SESSION[self::$config['CSRFP_TOKEN']])
254-
&& (self::isValidToken($_POST[self::$config['CSRFP_TOKEN']]))
255-
)) {
264+
if (!($token && isset($_SESSION[self::$config['CSRFP_TOKEN']])
265+
&& (self::isValidToken($token)))) {
256266

257267
//action in case of failed validation
258-
self::failedValidationAction();
268+
self::failedValidationAction();
259269
} else {
260270
self::refreshToken(); //refresh token for successfull validation
261271
}
262272
} else if (!static::isURLallowed()) {
263-
264273
//currently for same origin only
265274
if (!(isset($_GET[self::$config['CSRFP_TOKEN']])
266275
&& isset($_SESSION[self::$config['CSRFP_TOKEN']])
@@ -275,6 +284,36 @@ public static function authorizePost()
275284
}
276285
}
277286

287+
/*
288+
* Fucntion: getTokenFromRequest
289+
* function to get token in case of POST request
290+
*
291+
* Parameters:
292+
* void
293+
*
294+
* Returns:
295+
* any (string / bool) - token retrieved from header or form payload
296+
*/
297+
private static function getTokenFromRequest() {
298+
// look for in $_POST, then header
299+
if (isset($_POST[self::$config['CSRFP_TOKEN']])) {
300+
return $_POST[self::$config['CSRFP_TOKEN']];
301+
}
302+
303+
if (function_exists('apache_request_headers')) {
304+
if (isset(apache_request_headers()[self::$config['CSRFP_TOKEN']])) {
305+
return apache_request_headers()[self::$config['CSRFP_TOKEN']];
306+
}
307+
}
308+
309+
if (self::$tokenHeaderKey === null) return false;
310+
if (isset($_SERVER[self::$tokenHeaderKey])) {
311+
return $_SERVER[self::$tokenHeaderKey];
312+
}
313+
314+
return false;
315+
}
316+
278317
/*
279318
* Function: isValidToken
280319
* function to check the validity of token in session array

test/csrfprotector_test.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,10 @@ public function testAuthorisePost_failedAction_6()
350350
}
351351

352352
/**
353-
* test authorise success
353+
* test authorise success with token in $_POST
354354
*/
355355
public function testAuthorisePost_success()
356356
{
357-
358357
$_SERVER['REQUEST_METHOD'] = 'POST';
359358
$_POST[csrfprotector::$config['CSRFP_TOKEN']]
360359
= $_GET[csrfprotector::$config['CSRFP_TOKEN']]
@@ -382,6 +381,34 @@ public function testAuthorisePost_success()
382381
// $this->assertTrue(csrfp_wrapper::checkHeader($_SESSION[csrfprotector::$config['CSRFP_TOKEN']][0])); // Combine these 3 later
383382
}
384383

384+
/**
385+
* test authorise success with token in header
386+
*/
387+
public function testAuthorisePost_success_2()
388+
{
389+
unset($_POST[csrfprotector::$config['CSRFP_TOKEN']]);
390+
$_SERVER['REQUEST_METHOD'] = 'POST';
391+
$serverKey = 'HTTP_' .strtoupper(csrfprotector::$config['CSRFP_TOKEN']);
392+
$serverKey = str_replace('-', '_', $serverKey);
393+
394+
$csrfp = new csrfProtector;
395+
$reflection = new \ReflectionClass(get_class($csrfp));
396+
$property = $reflection->getProperty('tokenHeaderKey');
397+
$property->setAccessible(true);
398+
// change value to false
399+
$property->setValue($csrfp, $serverKey);
400+
401+
$_SERVER[$serverKey] = $_SESSION[csrfprotector::$config['CSRFP_TOKEN']][0];
402+
$temp = $_SESSION[csrfprotector::$config['CSRFP_TOKEN']];
403+
404+
csrfprotector::authorizePost(); //will create new session and cookies
405+
$this->assertFalse($temp == $_SESSION[csrfprotector::$config['CSRFP_TOKEN']][0]);
406+
$this->assertTrue(csrfp_wrapper::checkHeader('Set-Cookie'));
407+
$this->assertTrue(csrfp_wrapper::checkHeader('csrfp_token'));
408+
// $this->assertTrue(csrfp_wrapper::checkHeader($_SESSION[csrfprotector::$config['CSRFP_TOKEN']][0])); // Combine these 3 later
409+
410+
}
411+
385412
/**
386413
* test for generateAuthToken()
387414
*/

0 commit comments

Comments
 (0)