Skip to content

Commit 98b60b0

Browse files
authored
Merge pull request #130 from mebjas/loggerFix
Change default logger to be based on php's error_log
2 parents 563132a + 5e776cf commit 98b60b0

16 files changed

+263
-398
lines changed

libs/README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ CSRFProtector configuration
22
==========================================
33

44
- `CSRFP_TOKEN`: name of the csrf nonce, used for cookie or posting as argument. default: `CSRFP-Token` (if left blank)
5-
- `logDirectory`: location of the directory at which log files will be saved, either **relative** to the default `config.php` file location or an **absolute** path. This is required for file based logging (default), Not needed, in case you override logging function to implement your logging logic. (View [Overriding logging function](https://github.com/mebjas/CSRF-Protector-PHP/wiki/Overriding-logging-function))
6-
<br>**Default value:** `../log/`
75
- `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, (<br>**Default:** `0` for both `GET` & `POST`):
86
* `0` Send **403, Forbidden** Header
97
* `1` **Strip the POST/GET query** and forward the request! unset($_POST)

libs/config.sample.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
/**
33
* Configuration file for CSRF Protector
44
* Necessary configurations are (library would throw exception otherwise)
5-
* ---- logDirectory
65
* ---- failedAuthAction
76
* ---- jsUrl
87
* ---- tokenLength
98
*/
109
return array(
11-
"CSRFP_TOKEN" => "",
12-
"logDirectory" => "../log",
10+
"CSRFP_TOKEN" => "",
1311
"failedAuthAction" => array(
1412
"GET" => 0,
1513
"POST" => 0),
@@ -26,5 +24,5 @@
2624
"disabledJavascriptMessage" => "This site attempts to protect users against <a href=\"https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29\">
2725
Cross-Site Request Forgeries </a> 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.
2826
See details of your web browser for how to enable JavaScript.",
29-
"verifyGetFor" => array()
27+
"verifyGetFor" => array()
3028
);

libs/csrf/LoggerInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* This file has implementation for LoggerInterface interface
3+
* CSRF Protector's Logger interface.
44
*/
55

66
if (!defined('__CSRF_PROTECTOR_LOGGER_INTERFACE__')) {

libs/csrf/csrfpCookieConfig.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ class csrfpCookieConfig
3535

3636
/**
3737
* Variable: $expire
38-
* expiry parameter in seconds from now for setcookie method, default is 30 minutes
38+
* expiry parameter in seconds from now for setcookie method, default is
39+
* 30 minutes
3940
* @var int
4041
*/
4142
public $expire = 1800;
@@ -48,10 +49,21 @@ class csrfpCookieConfig
4849
*/
4950
function __construct($cfg) {
5051
if ($cfg !== null) {
51-
if (isset($cfg['path'])) $this->path = $cfg['path'];
52-
if (isset($cfg['domain'])) $this->domain = $cfg['domain'];
53-
if (isset($cfg['secure'])) $this->secure = (bool) $cfg['secure'];
54-
if (isset($cfg['expire']) && $cfg['expire']) $this->expire = (int)$cfg['expire'];
52+
if (isset($cfg['path'])) {
53+
$this->path = $cfg['path'];
54+
}
55+
56+
if (isset($cfg['domain'])) {
57+
$this->domain = $cfg['domain'];
58+
}
59+
60+
if (isset($cfg['secure'])) {
61+
$this->secure = (bool) $cfg['secure'];
62+
}
63+
64+
if (isset($cfg['expire']) && $cfg['expire']) {
65+
$this->expire = (int)$cfg['expire'];
66+
}
5567
}
5668
}
5769
}

libs/csrf/csrfpDefaultLogger.php

Lines changed: 8 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,82 +8,33 @@
88
// to avoid multiple declaration errors
99
define('__CSRF_PROTECTOR_DEFAULT_LOGGER_', true);
1010

11-
class logDirectoryNotFoundException extends \exception {};
12-
class logFileWriteError extends \exception {};
13-
1411
/**
1512
* Default logger class for CSRF Protector.
1613
*
17-
* This is a file based logger class.
14+
* This implementation is based on PHP's default error_log implementation.
1815
*/
1916
class csrfpDefaultLogger implements LoggerInterface {
20-
2117
/**
22-
* Variable: $logDirectory
23-
* directory for file based logging
24-
*/
25-
private $logDirectory;
26-
27-
/**
28-
* Constructor
29-
*
30-
* Parameters:
31-
* $path - the path for logs to be stored (relative or absolute)
18+
* Sends error message to the defined error_handling routines.
3219
*
33-
* Returns:
34-
* void
35-
*
36-
* Throws:
37-
* logDirectoryNotFoundException - if log directory is not found
38-
*/
39-
function __construct($path) {
40-
// Check for relative path
41-
$this->logDirectory = __DIR__ . "/../" . $path;
42-
43-
44-
// If the relative log directory path does not exist try as an absolute path.
45-
if (!is_dir($this->logDirectory)) {
46-
$this->logDirectory = $path;
47-
}
48-
49-
if (!is_dir($this->logDirectory)) {
50-
throw new logDirectoryNotFoundException("OWASP CSRFProtector: Log Directory Not Found!");
51-
}
52-
}
53-
54-
/**
55-
* logging method
20+
* Based on PHP's default error_log method implementation.
5621
*
5722
* Parameters:
5823
* $message - the log message
5924
* $context - context array
6025
*
6126
* Return:
6227
* void
63-
*
64-
* Throws:
65-
* logFileWriteError - if unable to log an attack
6628
*/
6729
public function log($message, $context = array()) {
68-
// Append to the log file, or create it if it does not exist create
69-
$logFile = fopen($this->logDirectory ."/" . date("m-20y") . ".log", "a+");
70-
71-
// Throw exception if above fopen fails
72-
if (!$logFile) {
73-
throw new logFileWriteError("OWASP CSRFProtector: Unable to write to the log file");
74-
}
75-
7630
$context['timestamp'] = time();
7731
$context['message'] = $message;
7832

7933
// Convert log array to JSON format to be logged
80-
$context = json_encode($context) .PHP_EOL;
81-
82-
// Append log to the file
83-
fwrite($logFile, $context);
84-
85-
// Close the file handler
86-
fclose($logFile);
34+
$contextString = "OWASP CSRF Protector PHP "
35+
.json_encode($context)
36+
.PHP_EOL;
37+
error_log($contextString, /* message_type= */ 0);
8738
}
8839
}
89-
}
40+
}

libs/csrf/csrfprotector.php

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
if (!defined('__CSRF_PROTECTOR__')) {
1111
define('__CSRF_PROTECTOR__', true); // to avoid multiple declaration errors
1212

13-
// name of HTTP POST variable for authentication
13+
// Name of HTTP POST variable for authentication
1414
define("CSRFP_TOKEN","CSRFP-Token");
1515

1616
// We insert token name and list of url patterns for which
@@ -19,13 +19,13 @@
1919
define("CSRFP_FIELD_TOKEN_NAME", "csrfp_hidden_data_token");
2020
define("CSRFP_FIELD_URLS", "csrfp_hidden_data_urls");
2121

22-
/**
23-
* child exception classes
24-
*/
22+
/** Indicates configuration file was not found. */
2523
class configFileNotFoundException extends \exception {};
26-
class jsFileNotFoundException extends \exception {};
27-
class baseJSFileNotFoundExceptio extends \exception {};
24+
25+
/** Indicates that configuration file is incomplete. */
2826
class incompleteConfigurationException extends \exception {};
27+
28+
/** Indicates that CSRF Protector is already initialized. */
2929
class alreadyInitializedException extends \exception {};
3030

3131
class csrfProtector
@@ -76,30 +76,38 @@ class csrfProtector
7676
* Variable: $config
7777
* config file for CSRFProtector
7878
* @var int Array, length = 6
79-
* Property: #1: failedAuthAction (int) => action to be taken in case autherisation fails
80-
* Property: #2: logDirectory (string) => directory in which log will be saved
81-
* Property: #3: customErrorMessage (string) => custom error message to be sent in case
82-
* of failed authentication
83-
* Property: #4: jsFile (string) => location of the CSRFProtector js file
84-
* Property: #5: tokenLength (int) => default length of hash
85-
* Property: #6: disabledJavascriptMessage (string) => error message if client's js is disabled
79+
* Property: #1: failedAuthAction (int) => action to be taken in case
80+
* autherisation fails.
81+
* Property: #3: customErrorMessage (string) => custom error message to
82+
* be sent in case of failed authentication.
83+
* Property: #4: jsFile (string) => location of the CSRFProtector js
84+
* file.
85+
* Property: #5: tokenLength (int) => default length of hash.
86+
* Property: #6: disabledJavascriptMessage (string) => error message if
87+
* client's js is disabled.
88+
*
89+
* TODO(mebjas): this field should be private
8690
*/
8791
public static $config = array();
8892

8993
/*
9094
* Variable: $requiredConfigurations
9195
* Contains list of those parameters that are required to be there
9296
* in config file for csrfp to work
97+
*
98+
* TODO(mebjas): this field should be private
9399
*/
94-
public static $requiredConfigurations = array('logDirectory', 'failedAuthAction', 'jsUrl', 'tokenLength');
100+
public static $requiredConfigurations = array(
101+
'failedAuthAction', 'jsUrl', 'tokenLength');
95102

96103
/*
97104
* Function: function to initialise the csrfProtector work flow
98105
*
99106
* Parameters:
100-
* $length - length of CSRF_AUTH_TOKEN to be generated
101-
* $action - int array, for different actions to be taken in case of failed validation
102-
* $logger - custom logger class object
107+
* $length - (int) length of CSRF_AUTH_TOKEN to be generated.
108+
* $action - (int array), for different actions to be taken in case of
109+
* failed validation.
110+
* $logger - (LoggerInterface) custom logger class object.
103111
*
104112
* Returns:
105113
* void
@@ -179,11 +187,11 @@ public static function init($length = null, $action = null, $logger = null)
179187
implode(', ', $missingConfiguration) . ' value(s)');
180188
}
181189

182-
// Iniialize the logger class
190+
// Initialize the logger class
183191
if ($logger !== null) {
184192
self::$logger = $logger;
185193
} else {
186-
self::$logger = new csrfpDefaultLogger(self::$config['logDirectory']);
194+
self::$logger = new csrfpDefaultLogger();
187195
}
188196

189197
// Authorise the incoming request
@@ -212,9 +220,8 @@ public static function init($length = null, $action = null, $logger = null)
212220
*
213221
* Returns:
214222
* void
215-
*
216-
* Throws:
217-
* logDirectoryNotFoundException - if log directory is not found
223+
*
224+
* TODO(mebjas): this method should be private.
218225
*/
219226
public static function authorizePost()
220227
{
@@ -539,7 +546,8 @@ protected static function logCSRFattack()
539546
$context['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
540547
$context['requestType'] = self::$requestType;
541548
$context['cookie'] = $_COOKIE;
542-
self::$logger->log("OWASP CSRF PROTECTOR VALIDATION FAILURE", $context);
549+
self::$logger->log(
550+
"OWASP CSRF PROTECTOR VALIDATION FAILURE", $context);
543551
}
544552

545553
/*

log/.htaccess

Lines changed: 0 additions & 1 deletion
This file was deleted.

log/index.php

Lines changed: 0 additions & 7 deletions
This file was deleted.

readme.md

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ CSRF Protector
33
[![Todo Status](http://todofy.org/b/mebjas/CSRF-Protector-PHP)](http://todofy.org/r/mebjas/CSRF-Protector-PHP) [![Build Status](https://travis-ci.org/mebjas/CSRF-Protector-PHP.svg?branch=master)](https://travis-ci.org/mebjas/CSRF-Protector-PHP)
44
<br>CSRF protector php, a standalone php library for csrf mitigation in web applications. Easy to integrate in any php web app.
55

6-
Add to your project using packagist
7-
==========
6+
# Add to your project using packagist
87
Add a `composer.json` file to your project directory
98
```json
109
{
@@ -16,61 +15,60 @@ Add to your project using packagist
1615
Then open terminal (or command prompt), move to project directory and run
1716
```shell
1817
composer install
19-
```
20-
OR
21-
```
18+
19+
## Or alternatively
20+
2221
php composer.phar install
2322
```
24-
This will add CSRFP (library will be downloaded at ./vendor/owasp/csrf-protector-php) to your project directory. View [packagist.org](https://packagist.org/) for more help with composer!
23+
This will add CSRFP (library will be downloaded at `./vendor/owasp/csrf-protector-php`) to your project directory. View [packagist.org](https://packagist.org/) for more help with composer!
2524

26-
Configuration
27-
==========
25+
# Configuration
2826
For composer installations: Copy the config.sample.php file into your root folder at config/csrf_config.php
2927
For non-composer installations: Copy the `libs/csrf/config.sample.php` file into `libs/csrf/config.php`
3028
Edit config accordingly. See Detailed Information link below.
3129

3230
[Link to wiki - Editing Configurations & Mandatory requirements before using this library](https://github.com/mebjas/CSRF-Protector-PHP/wiki/Configurations)
3331

34-
How to use
35-
==========
32+
# How to use
3633
```php
3734
<?php
3835
include_once __DIR__ .'/vendor/owasp/csrf-protector-php/libs/csrf/csrfprotector.php';
3936

40-
//Initialise CSRFGuard library
37+
// Initialise CSRFProtector library
4138
csrfProtector::init();
4239
```
4340
simply include the library and call the `init()` function!
4441

45-
### Detailed information @[Project wiki on github](https://github.com/mebjas/CSRF-Protector-PHP/wiki)
46-
47-
### More information @[OWASP wiki](https://www.owasp.org/index.php/CSRFProtector_Project)
48-
49-
### Contribute
42+
### More information
43+
- [Project wiki on Github](https://github.com/mebjas/CSRF-Protector-PHP/wiki)
44+
- [OWASP wiki](https://www.owasp.org/index.php/CSRFProtector_Project)
5045

51-
* Fork the repo
52-
* Create your branch
53-
* Commit your changes
54-
* Create a pull request
55-
56-
### Note
57-
This version (`master`) requires the clients to have Javascript enabled. However if your application can work without javascript & you require a nojs version of this library, check our [nojs version](https://github.com/mebjas/CSRF-Protector-PHP/tree/nojs-support)
58-
59-
## Discussion
46+
## Discussions
6047
Join Discussions at [Google Group \ OWASP \ CSRF Protector](https://groups.google.com/a/owasp.org/forum/#!forum/csrfprotector-project)
6148

62-
~~Join Discussions on the [mailing list](https://lists.owasp.org/mailman/listinfo/owasp-csrfprotector)~~
63-
64-
For any other queries contact me at: **[email protected]**
49+
For any other queries contact me at: [email protected] | [email protected]
6550

6651
## How to contribute?
67-
Well, there are various ways to contribute to this project. Find few of them listed below:
52+
### General steps
53+
- Fork the repo
54+
- Create your branch
55+
- Commit your changes
56+
- Create a pull request
57+
58+
### More?
59+
Well, there are various ways to contribute to this project. Find a few of them listed below:
6860
- Found a bug? Raise a bug in [the issue page](https://github.com/mebjas/CSRF-Protector-PHP/issues?q=is%3Aissue+is%3Aopen+label%3Abug). Please make sure it's not a duplicate of an existing issue.
69-
- Have a feature request? Raise one at [the issue page](https://github.com/mebjas/CSRF-Protector-PHP/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement). As mentioned above please do a basic check if this `enhancement` exist in mentioned link.
61+
- Have a feature request? Raise one at [the issue page](https://github.com/mebjas/CSRF-Protector-PHP/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement). As mentioned above please do a basic check if this `enhancement` exists in the mentioned link.
7062
- Want to contribute code to this project?
71-
- Best way to start is by picking up one of [the issues with `Up For Grab` label](https://github.com/mebjas/CSRF-Protector-PHP/issues?q=is%3Aissue+is%3Aopen+label%3A%22Up+For+Grabs%22). Leave a comment, that you intend to help on this > fork > send a pull request to `master branch`.
63+
- The best way to start is by picking up one of the existing [issues with `Up For Grab` label](https://github.com/mebjas/CSRF-Protector-PHP/issues?q=is%3Aissue+is%3Aopen+label%3A%22Up+For+Grabs%22).
64+
- Leave a comment, that you intend to help on this > then fork > and then send a pull request to `master branch`.
7265

73-
### FAQ:
66+
## FAQ:
7467
1. What happens if token expires? - https://github.com/mebjas/CSRF-Protector-PHP/wiki/what-if-token-expires
75-
2. Secure flag in cookie? - https://github.com/mebjas/CSRF-Protector-PHP/issues/54
68+
2. Secure flag in a cookie? - https://github.com/mebjas/CSRF-Protector-PHP/issues/54
7669
3. NoJS support? - https://github.com/mebjas/CSRF-Protector-PHP/tree/nojs-support
70+
71+
## Appendix
72+
73+
### JS not supported?
74+
This version (in `master` branch) requires the clients to have Javascript enabled. However if your application can work without javascript & you require a nojs version of this library, check our nojs version

0 commit comments

Comments
 (0)