diff --git a/.gitignore b/.gitignore index 21484c4..685b296 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ phpunit.phar -coverage/* \ No newline at end of file +coveralls.phar + +coverage/ +vendor/ +build/ +log/*.log diff --git a/js/csrfprotector.js b/js/csrfprotector.js index 0d22955..b339c56 100644 --- a/js/csrfprotector.js +++ b/js/csrfprotector.js @@ -20,16 +20,16 @@ var CSRFP = { * Array of patterns of url, for which csrftoken need to be added * In case of GET request also, provided from server * - * @var string array + * @var {Array} */ checkForUrls: [], /** * Function to check if a certain url is allowed to perform the request * With or without csrf token * - * @param: string, url + * @param {string} url * - * @return: boolean, true if csrftoken is not needed + * @return {Boolean} true if csrftoken is not needed * false if csrftoken is needed */ _isValidGetRequest: function(url) { @@ -41,12 +41,12 @@ var CSRFP = { } return true; }, - /** - * function to get Auth key from cookie Andreturn it to requesting function + /** + * Function to get Auth key from cookie and return it to requesting function * * @param: void * - * @return: string, csrftoken retrieved from cookie + * @return {string|Boolean} csrftoken retrieved from cookie */ _getAuthKey: function() { var re = new RegExp(CSRFP.CSRFP_TOKEN +"=([^;]+)(;|$)"); @@ -60,9 +60,9 @@ var CSRFP = { /** * Function to get domain of any url * - * @param: string, url + * @param {string} url * - * @return: string, domain of url + * @return {string} domain of url */ _getDomain: function(url) { if (url.indexOf("http://") !== 0 @@ -72,11 +72,11 @@ var CSRFP = { }, /** * Function to create and return a hidden input element - * For stroing the CSRFP_TOKEN + * For storing the CSRFP_TOKEN * - * @param void + * @param: void * - * @return input element + * @return {HTMLInputElement} input element */ _getInputElt: function() { var hiddenObj = document.createElement("input"); @@ -88,11 +88,11 @@ var CSRFP = { }, /** * Returns absolute path for relative path - * - * @param base, base url - * @param relative, relative url * - * @return absolute path (string) + * @param {string} base base url + * @param {string} relative relative url + * + * @return {string} absolute path */ _getAbsolutePath: function(base, relative) { var stack = base.split("/"); @@ -102,22 +102,22 @@ var CSRFP = { stack.pop(); for (var i = 0; i < parts.length; i++) { - if (parts[i] == ".") + if (parts[i] === ".") continue; - if (parts[i] == "..") + if (parts[i] === "..") stack.pop(); else stack.push(parts[i]); } return stack.join("/"); }, - /** - * Remove jcsrfp-token run fun and then put them back + /** + * Remove jcsrfp-token run fun and then put them back * - * @param function - * @param reference form obj + * @param {function} fun + * @param {object} obj reference form obj * - * @retrun function + * @return function */ _csrfpWrap: function(fun, obj) { return function(event) { @@ -139,7 +139,7 @@ var CSRFP = { /** * Initialises the CSRFProtector js script * - * @param void + * @param: void * * @return void */ @@ -169,7 +169,7 @@ var CSRFP = { function csrfprotector_init() { - // Call the init funcion + // Call the init function CSRFP._init(); // definition of basic FORM submit event handler to intercept the form request @@ -181,7 +181,7 @@ function csrfprotector_init() { //modify token to latest value event.target[CSRFP.CSRFP_TOKEN].value = CSRFP._getAuthKey(); } - } + }; //================================================================== // Adding csrftoken to request resulting from
submissions @@ -192,10 +192,10 @@ function csrfprotector_init() { document.querySelector('body').addEventListener('submit', function(event) { if (event.target.tagName.toLowerCase() === 'form') { BasicSubmitInterceptor(event); - }; + } }); - // intial binding + // initial binding // for(var i = 0; i < document.forms.length; i++) { // document.forms[i].addEventListener("submit", BasicSubmitInterceptor); // } @@ -211,7 +211,7 @@ function csrfprotector_init() { if (!this.getElementsByClassName(CSRFP.CSRFP_TOKEN).length) this.appendChild(CSRFP._getInputElt()); this.submit_(); - } + }; /** @@ -227,12 +227,12 @@ function csrfprotector_init() { } else { this.addEventListener_(eventType, fun, bubble); } - } + }; /** * Add wrapper for IE's attachEvent * todo - check for method - * todo - typeof is now obselete for IE 11, use some other method. + * todo - typeof is now obsolete for IE 11, use some other method. */ if (typeof HTMLFormElement.prototype.attachEvent !== 'undefined') { HTMLFormElement.prototype.attachEvent_ = HTMLFormElement.prototype.attachEvent; @@ -254,13 +254,13 @@ function csrfprotector_init() { /** * Wrapper to XHR open method - * Add a property method to XMLHttpRequst class + * Add a property method to XMLHttpRequest class * @param: all parameters to XHR open method * @return: object returned by default, XHR open method */ function new_open(method, url, async, username, password) { this.method = method; - var isAbsolute = (url.indexOf("./") === -1) ? true : false; + var isAbsolute = (url.indexOf("./") === -1); if (!isAbsolute) { var base = location.protocol +'//' +location.host + location.pathname; @@ -281,7 +281,7 @@ function csrfprotector_init() { /** * Wrapper to XHR send method - * Add query paramter to XHR object + * Add query parameter to XHR object * * @param: all parameters to XHR send method * @@ -313,7 +313,7 @@ function csrfprotector_init() { // Rules: // Rewrite those urls which matches the regex sent by Server // Ignore cross origin urls & internal links (one with hashtags) - // Append the token to those url already containig GET query parameter(s) + // Append the token to those url already containing GET query parameter(s) // Add the token to those which does not contain GET query parameter(s) //================================================================== @@ -322,9 +322,9 @@ function csrfprotector_init() { var href = event.target.href; if(typeof href === "string") { - var urlDisect = href.split('#'); - var url = urlDisect[0]; - var hash = urlDisect[1]; + var urlParts = href.split('#'); + var url = urlParts[0]; + var hash = urlParts[1]; if(CSRFP._getDomain(url).indexOf(document.domain) === -1 || CSRFP._isValidGetRequest(url)) { diff --git a/js/index.php b/js/index.php index 03e25a6..c512e09 100644 --- a/js/index.php +++ b/js/index.php @@ -1,7 +1,7 @@ **Default value:** `../log/` - `failedAuthAction`: Action code (integer) for action to be taken in case of failed validation. Has two different values for bot `GET` and `POST`. Different action codes are specified as follows, (
**Default:** `0` for both `GET` & `POST`): -* `0` Send **403, Forbidden** Header -* `1` **Strip the POST/GET query** and forward the request! unset($_POST) -* `2` **Redirect to custom error page** mentioned in `errorRedirectionPage` -* `3` **Show custom error message** to user, mentioned in `customErrorMessage` -* `4` Send **500, Internal Server Error** header + * `0` Send **403, Forbidden** Header + * `1` **Strip the POST/GET query** and forward the request! unset($_POST) + * `2` **Redirect to custom error page** mentioned in `errorRedirectionPage` + * `3` **Show custom error message** to user, mentioned in `customErrorMessage` + * `4` Send **500, Internal Server Error** header - `errorRedirectionPage`: **Absolute url** of the file to which user should be redirected.
**Default: null** - `customErrorMessage`: **Error Message** to be shown to user. Only this text will be shown!
**Default: null** - - `jsUrl`: **Absolute url** of the js file. (See [Setting up](https://github.com/mebjas/CSRF-Protector-PHP/wiki/Setting-up-CSRF-Protector-PHP-in-your-web-application) for more information) + - `jsUrl`: **Absolute url** of the js file or `FALSE` if the js file will be added to the page manually. (See [Setting up](https://github.com/mebjas/CSRF-Protector-PHP/wiki/Setting-up-CSRF-Protector-PHP-in-your-web-application) for more information) - `tokenLength`: length of csrfp token, Default `10` - - `cookieConfig`: Array of parameter values for set cookie method. supports three properties: `path`, `domain`, `secure`. They have same meaning as respective parameters of `setcookie` method: [learn more - php.net] + - `cookieConfig`: Array of parameter values for set cookie method. supports three properties: `path`, `domain`, `secure` and `expire`. They have same meaning as respective parameters of `setcookie` method: [learn more - php.net] - `disabledJavascriptMessage`: messaged to be shown if js is disabled (string) - `verifyGetFor`: regex rules for those urls for which csrfp validation should be enabled for `GET` requests also. (View [verifyGetFor rules](https://github.com/mebjas/CSRF-Protector-PHP/wiki/verifyGetFor-rules) for more information) diff --git a/libs/config.sample.php b/libs/config.sample.php index e16145c..ebb526a 100755 --- a/libs/config.sample.php +++ b/libs/config.sample.php @@ -20,7 +20,8 @@ "cookieConfig" => array( "path" => '', "domain" => '', - "secure" => false + "secure" => false, + "expire" => '', ), "disabledJavascriptMessage" => "This site attempts to protect users against Cross-Site Request Forgeries attacks. In order to do so, you must have JavaScript enabled in your web browser otherwise this site will fail to work correctly for you. diff --git a/libs/csrf/csrfprotector.php b/libs/csrf/csrfprotector.php index 7e097a2..3ee1ddf 100755 --- a/libs/csrf/csrfprotector.php +++ b/libs/csrf/csrfprotector.php @@ -48,30 +48,31 @@ class cookieConfig */ public $secure = false; + /** + * Variable: $expire + * expiry parameter in seconds from now for setcookie method, default is 30 minutes + * @var int + */ + public $expire = 1800; + /** * Function: constructor * * Parameters: - * $cfg - config array loaded from config file; + * @param $cfg - config array loaded from config file; */ function __construct($cfg) { if ($cfg !== null) { if (isset($cfg['path'])) $this->path = $cfg['path']; if (isset($cfg['domain'])) $this->domain = $cfg['domain']; if (isset($cfg['secure'])) $this->secure = (bool) $cfg['secure']; + if (isset($cfg['expire']) && $cfg['expire']) $this->expire = (int)$cfg['expire']; } } } class csrfProtector { - /* - * Variable: $cookieExpiryTime - * expiry time for cookie - * @var int - */ - public static $cookieExpiryTime = 1800; //30 minutes - /* * Variable: $isSameOrigin * flag for cross origin/same origin request @@ -102,7 +103,7 @@ class csrfProtector /* * Variable: $requestType - * Varaible to store weather request type is post or get + * Variable to store whether request type is post or get * @var string */ protected static $requestType = "GET"; @@ -164,7 +165,7 @@ public static function init($length = null, $action = null) //start session in case its not if (session_id() == '') - session_start(); + session_start(); /* * load configuration file and properties @@ -202,20 +203,20 @@ public static function init($length = null, $action = null) self::$config['cookieConfig'] = array(); self::$cookieConfig = new cookieConfig(self::$config['cookieConfig']); - // Validate the config if everythings filled out - // TODO: collect all missing values and throw exception together + // Validate the config if everything is filled out + $missingConfiguration = []; foreach (self::$requiredConfigurations as $value) { - if (!isset(self::$config[$value]) || self::$config[$value] == '') { - throw new incompleteConfigurationException( - sprintf( - "OWASP CSRFProtector: Incomplete configuration file, Value: %s missing ", - $value - ) - ); - exit; + if (!isset(self::$config[$value]) || self::$config[$value] === '') { + $missingConfiguration[] = $value; } } + if ($missingConfiguration) { + throw new incompleteConfigurationException( + 'OWASP CSRFProtector: Incomplete configuration file: missing ' . + implode(', ', $missingConfiguration) . ' value(s)'); + } + // Authorise the incoming request self::authorizePost(); @@ -267,7 +268,7 @@ public static function authorizePost() //action in case of failed validation self::failedValidationAction(); } else { - self::refreshToken(); //refresh token for successfull validation + self::refreshToken(); //refresh token for successful validation } } else if (!static::isURLallowed()) { //currently for same origin only @@ -279,13 +280,13 @@ public static function authorizePost() //action in case of failed validation self::failedValidationAction(); } else { - self::refreshToken(); //refresh token for successfull validation + self::refreshToken(); //refresh token for successful validation } } } /* - * Fucntion: getTokenFromRequest + * Function: getTokenFromRequest * function to get token in case of POST request * * Parameters: @@ -301,8 +302,9 @@ private static function getTokenFromRequest() { } if (function_exists('apache_request_headers')) { - if (isset(apache_request_headers()[self::$config['CSRFP_TOKEN']])) { - return apache_request_headers()[self::$config['CSRFP_TOKEN']]; + $apacheRequestHeaders = apache_request_headers(); + if (isset($apacheRequestHeaders[self::$config['CSRFP_TOKEN']])) { + return $apacheRequestHeaders[self::$config['CSRFP_TOKEN']]; } } @@ -356,9 +358,6 @@ private static function isValidToken($token) { */ private static function failedValidationAction() { - if (!file_exists(__DIR__ ."/../" .self::$config['logDirectory'])) - throw new logDirectoryNotFoundException("OWASP CSRFProtector: Log Directory Not Found!"); - //call the logging function static::logCSRFattack(); @@ -382,6 +381,8 @@ private static function failedValidationAction() //redirect to custom error page $location = self::$config['errorRedirectionPage']; header("location: $location"); + exit(self::$config['customErrorMessage']); + break; case 3: //send custom error message exit(self::$config['customErrorMessage']); @@ -432,8 +433,8 @@ public static function refreshToken() setcookie( self::$config['CSRFP_TOKEN'], - $token, - time() + self::$cookieExpiryTime, + $token, + time() + self::$cookieConfig->expire, self::$cookieConfig->path, self::$cookieConfig->domain, (bool) self::$cookieConfig->secure); @@ -496,45 +497,48 @@ public static function generateAuthToken() public static function ob_handler($buffer, $flags) { // Even though the user told us to rewrite, we should do a quick heuristic - // to check if the page is *actually* HTML. We don't begin rewriting until - // we hit the first message to outgoing HTML output, - //informing the user to enable js for CSRFProtector to work - //best section to add, after tag - $buffer = preg_replace("/]*>/", "$0 ", $buffer); - - $hiddenInput = '' .PHP_EOL; - - $hiddenInput .= ''; - - //implant hidden fields with check url information for reading in javascript - $buffer = str_ireplace('', $hiddenInput . '', $buffer); - - //implant the CSRFGuard js file to outgoing script - $script = '' . PHP_EOL; - $buffer = str_ireplace('', $script . '', $buffer, $count); - - if (!$count) - $buffer .= $script; - - return $buffer; + // to check if the page is *actually* HTML. We don't begin rewriting until + // we hit the first message to outgoing HTML output, + //informing the user to enable js for CSRFProtector to work + //best section to add, after tag + $buffer = preg_replace("/]*>/", "$0 ", $buffer); + + $hiddenInput = '' .PHP_EOL; + + $hiddenInput .= ''; + + //implant hidden fields with check url information for reading in javascript + $buffer = str_ireplace('', $hiddenInput . '', $buffer); + + if (self::$config['jsUrl']) { + //implant the CSRFGuard js file to outgoing script + $script = ''; + $buffer = str_ireplace('', $script . PHP_EOL . '', $buffer, $count); + + // Add the script to the end if the body tag was not closed + if (!$count) + $buffer .= $script; + } + + return $buffer; } /* @@ -544,7 +548,7 @@ public static function ob_handler($buffer, $flags) * Parameters: * void * - * Retruns: + * Returns: * void * * Throws: @@ -552,9 +556,18 @@ public static function ob_handler($buffer, $flags) */ protected static function logCSRFattack() { - //if file doesnot exist for, create it - $logFile = fopen(__DIR__ ."/../" .self::$config['logDirectory'] - ."/" .date("m-20y") .".log", "a+"); + $logDirectory = __DIR__ . "/../" . self::$config['logDirectory']; + + // If the relative log directory path does not exist try as an absolute path + if (!is_dir($logDirectory)) { + $logDirectory = self::$config['logDirectory']; + } + + if (!is_dir($logDirectory)) + throw new logDirectoryNotFoundException("OWASP CSRFProtector: Log Directory Not Found!"); + + // Append to the log file, or create it if it does not exist create + $logFile = fopen("$logDirectory/" . date("m-20y") . ".log", "a+"); //throw exception if above fopen fails if (!$logFile) @@ -613,7 +626,7 @@ private static function getCurrentUrl() /* * Function: isURLallowed - * Function to check if a url mataches for any urls + * Function to check if a url matches for any urls * Listed in config file * * Parameters: diff --git a/libs/csrf/index.php b/libs/csrf/index.php index 03e25a6..c512e09 100644 --- a/libs/csrf/index.php +++ b/libs/csrf/index.php @@ -1,7 +1,7 @@ array( "path" => '', "domain" => '', - "secure" => false + "secure" => false, + "expire" => '', ), "disabledJavascriptMessage" => "This site attempts to protect users against Cross-Site Request Forgeries attacks. In order to do so, you must have JavaScript enabled in your web browser otherwise this site will fail to work correctly for you. diff --git a/test/config.testInit_incompleteConfigurationException.php b/test/config.testInit_incompleteConfigurationException.php new file mode 100644 index 0000000..a778c51 --- /dev/null +++ b/test/config.testInit_incompleteConfigurationException.php @@ -0,0 +1,30 @@ + "csrfp_token", +// "logDirectory" => "../log", +// "failedAuthAction" => array( +// "GET" => 0, +// "POST" => 0), + "errorRedirectionPage" => "", + "customErrorMessage" => "", +// "jsUrl" => "http://localhost/csrfp/js/csrfprotector.js", +// "tokenLength" => 10, + "cookieConfig" => array( + "path" => '', + "domain" => '', + "secure" => false, + "expire" => '', + ), + "disabledJavascriptMessage" => "This site attempts to protect users against + Cross-Site Request Forgeries attacks. In order to do so, you must have JavaScript enabled in your web browser otherwise this site will fail to work correctly for you. + See details of your web browser for how to enable JavaScript.", + "verifyGetFor" => array() +); \ No newline at end of file diff --git a/test/config.testInit_withoutInjectedCSRFGuardScript.php b/test/config.testInit_withoutInjectedCSRFGuardScript.php new file mode 100644 index 0000000..1cc1d61 --- /dev/null +++ b/test/config.testInit_withoutInjectedCSRFGuardScript.php @@ -0,0 +1,30 @@ + "csrfp_token", + "logDirectory" => "../log", + "failedAuthAction" => array( + "GET" => 0, + "POST" => 0), + "errorRedirectionPage" => "", + "customErrorMessage" => "", + "jsUrl" => false, + "tokenLength" => 10, + "cookieConfig" => array( + "path" => '', + "domain" => '', + "secure" => false, + "expire" => '', + ), + "disabledJavascriptMessage" => "This site attempts to protect users against + Cross-Site Request Forgeries attacks. In order to do so, you must have JavaScript enabled in your web browser otherwise this site will fail to work correctly for you. + See details of your web browser for how to enable JavaScript.", + "verifyGetFor" => array() +); \ No newline at end of file diff --git a/test/csrfprotector_test.php b/test/csrfprotector_test.php index 52a1279..c72698b 100644 --- a/test/csrfprotector_test.php +++ b/test/csrfprotector_test.php @@ -12,7 +12,8 @@ class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase'); class csrfp_wrapper extends csrfprotector { /** - * Function to provide wrapper methode to set the protected var, requestType + * Function to provide wrapper method to set the protected var, requestType + * @param string $type */ public static function changeRequestType($type) { @@ -22,6 +23,8 @@ public static function changeRequestType($type) /** * Function to check for a string value anywhere within HTTP response headers * Returns true on first match of $needle in header names or values + * @param string $needle + * @return bool */ public static function checkHeader($needle) { @@ -36,6 +39,8 @@ public static function checkHeader($needle) /** * Function to return the string value of the last response header * identified by name $needle + * @param string $needle + * @return string */ public static function getHeaderValue($needle) { @@ -56,12 +61,12 @@ public static function getHeaderValue($needle) */ class Helper { /** - * Function to recusively delete a dir + * Function to recursively delete a dir */ public static function delTree($dir) { $files = array_diff(scandir($dir), array('.','..')); foreach ($files as $file) { - (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); + (is_dir("$dir/$file")) ? self::delTree("$dir/$file") : unlink("$dir/$file"); } return rmdir($dir); } @@ -74,12 +79,12 @@ public static function delTree($dir) { class csrfp_test extends PHPUnit_Framework_TestCase { /** - * @var to hold current configurations + * @var array to hold current configurations */ protected $config = array(); /** - * @var log directory for testing + * @var string log directory for testing */ private $logDir; @@ -143,32 +148,41 @@ public function testRefreshToken() } /** - * Function to check cookieconfig class + * Function to check cookieConfig class */ public function testCookieConfigClass() { $cfg = array( "path" => "abcd", "secure" => true, "domain" => "abcd", + "expire" => 600, ); // simple test $cookieConfig = new cookieConfig($cfg); - $this->assertEquals($cookieConfig->path, "abcd"); - $this->assertEquals($cookieConfig->domain, "abcd"); - $this->assertEquals($cookieConfig->secure, true); + $this->assertEquals("abcd", $cookieConfig->path); + $this->assertEquals("abcd", $cookieConfig->domain); + $this->assertEquals(true, $cookieConfig->secure); + $this->assertEquals(600, $cookieConfig->expire); // default value test $cookieConfig = new cookieConfig(array()); - $this->assertEquals($cookieConfig->path, ''); - $this->assertEquals($cookieConfig->domain, ''); - $this->assertEquals($cookieConfig->secure, false); + $this->assertEquals('', $cookieConfig->path); + $this->assertEquals('', $cookieConfig->domain); + $this->assertEquals(false, $cookieConfig->secure); + $this->assertEquals(1800, $cookieConfig->expire); // secure as string $cookieConfig = new cookieConfig(array('secure' => 'true')); - $this->assertEquals($cookieConfig->secure, true); + $this->assertEquals(true, $cookieConfig->secure); $cookieConfig = new cookieConfig(array('secure' => 'false')); - $this->assertEquals($cookieConfig->secure, true); + $this->assertEquals(true, $cookieConfig->secure); + + // expire as string + $cookieConfig = new cookieConfig(array('expire' => '600')); + $this->assertEquals(600, $cookieConfig->expire); + $cookieConfig = new cookieConfig(array('expire' => '')); + $this->assertEquals(1800, $cookieConfig->expire); } /** @@ -178,6 +192,7 @@ public function testSecureCookie() { $_SERVER['REQUEST_METHOD'] = 'POST'; $_SESSION[csrfprotector::$config['CSRFP_TOKEN']] = array('123abcd'); + csrfProtector::$config['tokenLength'] = 20; // this one would generally fails, as init was already called and now private static // property is set with secure as false; @@ -198,20 +213,29 @@ public function testSecureCookie() } /** - * test authorise post -> log directory exception + * test secure flag is set in the token cookie when requested */ - public function testAuthorisePost_logdirException() + public function testCookieExpireTime() { $_SERVER['REQUEST_METHOD'] = 'POST'; - csrfprotector::$config['logDirectory'] = 'unknown_location'; + $_SESSION[csrfprotector::$config['CSRFP_TOKEN']] = array('123abcd'); + csrfProtector::$config['tokenLength'] = 20; - try { - csrfprotector::authorizePost(); - } catch (logDirectoryNotFoundException $ex) { - $this->assertTrue(true); - return;; + // this one would generally fails, as init was already called and now private static + // property is already set; + $csrfp = new csrfProtector; + $reflection = new \ReflectionClass(get_class($csrfp)); + $property = $reflection->getProperty('cookieConfig'); + $property->setAccessible(true); + + // change value to 600 + $property->setValue($csrfp, new cookieConfig(array('expire' => 600))); + csrfprotector::refreshToken(); + // Check the expire date to the nearest minute in case the seconds does not match during test execution + $this->assertRegExp('/; expires=' . date('D, d-M-Y H:i', time() + 600) . ':\d\d GMT;?/', csrfp_wrapper::getHeaderValue('Set-Cookie')); + if(version_compare(phpversion(), '5.5', '>=')) { + $this->assertRegExp('/; Max-Age=600/', csrfp_wrapper::getHeaderValue('Set-Cookie')); } - $this->fail('logDirectoryNotFoundException has not been raised.'); } /** @@ -419,12 +443,12 @@ public function testGenerateAuthToken() $token2 = csrfprotector::generateAuthToken(); $this->assertFalse($token1 == $token2); - $this->assertEquals(strlen($token1), 20); + $this->assertEquals(20, strlen($token1)); $this->assertRegExp('/^[a-z0-9]{20}$/', $token1); csrfprotector::$config['tokenLength'] = 128; $token = csrfprotector::generateAuthToken(); - $this->assertEquals(strlen($token), 128); + $this->assertEquals(128, strlen($token)); $this->assertRegExp('/^[a-z0-9]{128}$/', $token); } @@ -433,6 +457,7 @@ public function testGenerateAuthToken() */ public function testob_handler() { + csrfprotector::$config['verifyGetFor'] = array(); csrfprotector::$config['disabledJavascriptMessage'] = 'test message'; csrfprotector::$config['jsUrl'] = 'http://localhost/test/csrf/js/csrfprotector.js'; @@ -449,10 +474,33 @@ public function testob_handler() $outLength = strlen($modifiedHTML); //Check if file has been modified - $this->assertFalse($outLength == $inpLength); - $this->assertTrue(strpos($modifiedHTML, '