Skip to content

Commit 3d2156c

Browse files
Merge pull request #79 from julienloizelet/feature/78-fix-session-and-redirect-issues
Feature/78 fix session and redirect issues
2 parents e92c82a + 80c938a commit 3d2156c

File tree

15 files changed

+85
-2159
lines changed

15 files changed

+85
-2159
lines changed

.github/workflows/test-suite.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
name: Test suite
22
on:
3-
push:
4-
branches:
5-
- main
6-
paths-ignore:
7-
- '**.md'
83
pull_request:
94
branches:
105
- main
@@ -33,7 +28,7 @@ jobs:
3328

3429
- name: Install DDEV
3530
env:
36-
DDEV_VERSION: v1.18.2
31+
DDEV_VERSION: v1.19.1
3732
run: |
3833
# @see https://ddev.readthedocs.io/en/stable/#installationupgrade-script-linux-and-macos-armarm64-and-amd64-architectures
3934
sudo apt-get -qq update

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ vendor
99
super-linter.log
1010
.php-cs-fixer.cache
1111
.php-cs-fixer.php
12+
tools/php-cs-fixer/composer.lock
1213

1314
# App
1415
/var/

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

77

8+
## [0.19.0] - 2022-03-24
9+
10+
### Added
11+
12+
- Add `excluded_uris` configuration to exclude some uris (was hardcoded to `/favicon.ico`)
13+
14+
### Changed
15+
- Change the redirection after captcha resolution to `/` (was `$_SERVER['REQUEST_URI']'`)
16+
17+
### Fixed
18+
- Fix Standalone bouncer session handling
19+
20+
821
## [0.18.0] - 2022-03-18
922
### Changed
1023
- *Breaking change*: Change `trust_ip_forward_array` symfony configuration node to an array of array.

docs/USER_GUIDE.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ Here is the list of available settings:
145145

146146
- `trust_ip_forward_array`: If you use a CDN, a reverse proxy or a load balancer, set an array of IPs. For other IPs, the bouncer will not trust the X-Forwarded-For header.
147147

148+
- `excluded_uris`: array of URIs that will not be bounced
149+
148150
##### Cache
149151

150152
- `cache_system`: Select from `phpfs` (File system cache), `redis` or `memcached`.
@@ -156,9 +158,9 @@ Here is the list of available settings:
156158

157159
- `memcached_dsn`: Will be used only if you choose Memcached as cache_system
158160

159-
- `cache_expiration_for_clean_ip`: Set the duration we keep in cache the fact that an IP is clean. In seconds. Defaults to 5.
161+
- `clean_ip_cache_duration`: Set the duration we keep in cache the fact that an IP is clean. In seconds. Defaults to 5.
160162

161-
- `cache_expiration_for_bad_ip`: Set the duration we keep in cache the fact that an IP is bad. In seconds. Defaults to 20.
163+
- `bad_ip_cache_duration`: Set the duration we keep in cache the fact that an IP is bad. In seconds. Defaults to 20.
162164

163165
- `stream_mode`: true to enable stream mode, false to enable the live mode. Default to false. By default, the `live mode` is enabled. The first time a stranger connects to your website, this mode means that the IP will be checked directly by the CrowdSec API. The rest of your user’s browsing will be even more transparent thanks to the fully customizable cache system. But you can also activate the `stream mode`. This mode allows you to constantly feed the bouncer with the malicious IP list via a background task (CRON), making it to be even faster when checking the IP of your visitors. Besides, if your site has a lot of unique visitors at the same time, this will not influence the traffic to the API of your CrowdSec instance.
164166

@@ -181,25 +183,45 @@ Here is the list of available settings:
181183
- Wording and css settings:
182184

183185
`theme_color_text_primary`
186+
184187
`theme_color_text_secondary`
188+
185189
`theme_color_text_button`
190+
186191
`theme_color_text_error_message`
192+
187193
`theme_color_background_page`
194+
188195
`theme_color_background_container`
196+
189197
`theme_color_background_button`
198+
190199
`theme_color_background_button_hover`
200+
191201
`theme_custom_css`
202+
192203
`theme_text_captcha_wall_tab_title`
204+
193205
`theme_text_captcha_wall_title`
206+
194207
`theme_text_captcha_wall_subtitle`
208+
195209
`theme_text_captcha_wall_refresh_image_link`
210+
196211
`theme_text_captcha_wall_captcha_placeholder`
212+
197213
`theme_text_captcha_wall_send_button`
214+
198215
`theme_text_captcha_wall_error_message`
216+
199217
`theme_text_captcha_wall_footer`
218+
200219
`theme_text_ban_wall_tab_title`
220+
201221
`theme_text_ban_wall_title`
222+
202223
`theme_text_ban_wall_subtitle`
224+
203225
`theme_text_ban_wall_footer`
204226

205227

scripts/auto-prepend/bounce.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88

99
use CrowdSecBouncer\StandaloneBounce;
1010

11+
12+
1113
$bounce = new StandaloneBounce();
1214

1315
/** @var $crowdSecStandaloneBouncerConfig */
14-
$bounce->safelyBounce($crowdSecStandaloneBouncerConfig);
16+
$bounce->safelyBounce($crowdSecStandaloneBouncerConfig);

scripts/auto-prepend/settings.example.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* Key generated by the cscli (CrowdSec cli) command like "cscli bouncers add bouncer-php-library"
99
*/
10-
'api_key'=> 'YOUR_BOUNCER_API_KEY',
10+
'api_key' => 'YOUR_BOUNCER_API_KEY',
1111

1212
/** Define the URL to your LAPI server, default to http://localhost:8080.
1313
*
@@ -37,7 +37,7 @@
3737
*
3838
* If not empty, it will be used for all remediation and geolocation processes.
3939
*/
40-
'forced_test_ip' => '1.2.3.4',
40+
'forced_test_ip' => '',
4141

4242
/** Select from 'bouncing_disabled', 'normal_bouncing' or 'flex_bouncing'.
4343
*
@@ -68,6 +68,11 @@
6868
*/
6969
'trust_ip_forward_array' => [],
7070

71+
/**
72+
* array of URIs that will not be bounced
73+
*/
74+
'excluded_uris' => ['/favicon.ico'],
75+
7176
// Select from 'phpfs' (File system cache), 'redis' or 'memcached'.
7277
'cache_system' => Constants::CACHE_SYSTEM_PHPFS,
7378

@@ -84,10 +89,10 @@
8489
'memcached_dsn' => 'memcached://localhost:11211',
8590

8691
// Set the duration we keep in cache the fact that an IP is clean. In seconds. Defaults to 5.
87-
'cache_expiration_for_clean_ip'=> Constants::CACHE_EXPIRATION_FOR_CLEAN_IP,
92+
'clean_ip_cache_duration'=> Constants::CACHE_EXPIRATION_FOR_CLEAN_IP,
8893

8994
// Optional. Set the duration we keep in cache the fact that an IP is bad. In seconds. Defaults to 20.
90-
'cache_expiration_for_bad_ip'=> Constants::CACHE_EXPIRATION_FOR_BAD_IP,
95+
'bad_ip_cache_duration'=> Constants::CACHE_EXPIRATION_FOR_BAD_IP,
9196

9297
/** true to enable stream mode, false to enable the live mode. Default to false.
9398
*

src/AbstractBounce.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,12 @@ protected function handleCaptchaRemediation($ip)
266266

267267
if (null === $this->getSessionVariable('crowdsec_captcha_has_to_be_resolved')) {
268268
// Set up the first captcha remediation.
269-
270269
$this->storeNewCaptchaCoupleInSession();
271270
$this->setSessionVariable('crowdsec_captcha_has_to_be_resolved', true);
272271
$this->setSessionVariable('crowdsec_captcha_resolution_failed', false);
273272
$this->setSessionVariable('crowdsec_captcha_resolution_redirect', 'POST' === $this->getHttpMethod() &&
274273
!empty($_SERVER['HTTP_REFERER']) ?
275-
$_SERVER['HTTP_REFERER'] : $_SERVER['REQUEST_URI']);
274+
$_SERVER['HTTP_REFERER'] : '/');
276275
}
277276

278277
// Display captcha page if this is required.

src/Bouncer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ public function configure(array $config): void
7474
$finalConfig['api_timeout'],
7575
$finalConfig['api_user_agent'],
7676
$finalConfig['api_key'],
77-
$finalConfig['cache_expiration_for_clean_ip'],
78-
$finalConfig['cache_expiration_for_bad_ip'],
77+
$finalConfig['clean_ip_cache_duration'],
78+
$finalConfig['bad_ip_cache_duration'],
7979
$finalConfig['fallback_remediation'],
8080
$finalConfig['geolocation']
8181
);

src/Configuration.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ public function getConfigTreeBuilder(): TreeBuilder
5656
->scalarPrototype()->end()
5757
->end()
5858
->end()
59+
->arrayNode('excluded_uris')
60+
->scalarPrototype()->end()
61+
->end()
5962
// Cache
6063
->booleanNode('stream_mode')->defaultValue(false)->end()
6164
->enumNode('cache_system')
@@ -65,10 +68,10 @@ public function getConfigTreeBuilder(): TreeBuilder
6568
->scalarNode('fs_cache_path')->end()
6669
->scalarNode('redis_dsn')->end()
6770
->scalarNode('memcached_dsn')->end()
68-
->integerNode('cache_expiration_for_clean_ip')
71+
->integerNode('clean_ip_cache_duration')
6972
->defaultValue(Constants::CACHE_EXPIRATION_FOR_CLEAN_IP)
7073
->end()
71-
->integerNode('cache_expiration_for_bad_ip')
74+
->integerNode('bad_ip_cache_duration')
7275
->defaultValue(Constants::CACHE_EXPIRATION_FOR_BAD_IP)
7376
->end()
7477
// Geolocation

src/Constants.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Constants
2020
public const DEFAULT_LAPI_URL = 'http://localhost:8080';
2121

2222
/** @var string The last version of this library */
23-
public const VERSION = 'v0.18.0';
23+
public const VERSION = 'v0.19.0';
2424

2525
/** @var string The user agent used to send request to LAPI */
2626
public const BASE_USER_AGENT = 'PHP CrowdSec Bouncer/'.self::VERSION;

src/RestClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public function request(
9999
'method' => $method,
100100
'uri' => $this->baseUri.$endpoint,
101101
'content' => 'POST' === $method ? $config['http']['content'] : null,
102-
//'header' => $header, # Do not display header to avoid logging sensible data
102+
// 'header' => $header, # Do not display header to avoid logging sensible data
103103
]);
104104

105105
$response = file_get_contents($this->baseUri.$endpoint, false, $context);

src/StandaloneBounce.php

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class StandaloneBounce extends AbstractBounce implements IBounce
3030
/**
3131
* @var string
3232
*/
33-
protected $session_name;
33+
const SESSION_NAME = 'crowdsec';
3434

3535
/**
3636
* Initialize the bouncer.
@@ -41,10 +41,6 @@ class StandaloneBounce extends AbstractBounce implements IBounce
4141
*/
4242
public function init(array $configs, array $forcedConfigs = []): Bouncer
4343
{
44-
if (\PHP_SESSION_NONE === session_status()) {
45-
$this->session_name = session_name('crowdsec');
46-
session_start();
47-
}
4844
// Convert array of string to array of array with comparable IPs
4945
if (\is_array(($configs['trust_ip_forward_array']))) {
5046
$forwardConfigs = $configs['trust_ip_forward_array'];
@@ -182,8 +178,8 @@ public function getBouncerInstance(array $settings, bool $forceReload = false):
182178
'fs_cache_path' => $this->getStringSettings('fs_cache_path'),
183179
'redis_dsn' => $this->getStringSettings('redis_dsn'),
184180
'memcached_dsn' => $this->getStringSettings('memcached_dsn'),
185-
'cache_expiration_for_clean_ip' => $this->getIntegerSettings('clean_ip_cache_duration'),
186-
'cache_expiration_for_bad_ip' => $this->getIntegerSettings('bad_ip_cache_duration'),
181+
'clean_ip_cache_duration' => $this->getIntegerSettings('clean_ip_cache_duration'),
182+
'bad_ip_cache_duration' => $this->getIntegerSettings('bad_ip_cache_duration'),
187183
// Geolocation
188184
'geolocation' => $this->getArraySettings('geolocation'),
189185
]);
@@ -345,11 +341,15 @@ public function getPostedVariable(string $name): ?string
345341
*/
346342
public function shouldBounceCurrentIp(): bool
347343
{
348-
// Don't bounce favicon calls
349-
if ('/favicon.ico' === $_SERVER['REQUEST_URI']) {
344+
$excludedURIs = $this->getArraySettings('excluded_uris');
345+
if (\in_array($_SERVER['REQUEST_URI'], $excludedURIs)) {
346+
$this->logger->debug('', [
347+
'type' => 'SHOULD_NOT_BOUNCE',
348+
'message' => 'This URI is excluded from bouncing: '.$_SERVER['REQUEST_URI'],
349+
]);
350+
350351
return false;
351352
}
352-
353353
$bouncingDisabled = (Constants::BOUNCING_LEVEL_DISABLED === $this->getStringSettings('bouncing_level'));
354354
if ($bouncingDisabled) {
355355
$this->logger->debug('', [
@@ -407,6 +407,10 @@ public function safelyBounce(array $configs): bool
407407
throw new BouncerException("$errstr (Error level: $errno)");
408408
});
409409
try {
410+
if (\PHP_SESSION_NONE === session_status()) {
411+
session_name(self::SESSION_NAME);
412+
session_start();
413+
}
410414
$this->init($configs);
411415
$this->run();
412416
$result = true;
@@ -421,11 +425,6 @@ public function safelyBounce(array $configs): bool
421425
if ($this->displayErrors) {
422426
throw $e;
423427
}
424-
} finally {
425-
if (\PHP_SESSION_NONE !== session_status()) {
426-
session_write_close();
427-
session_name($this->session_name);
428-
}
429428
}
430429
restore_error_handler();
431430

tests/LoadPaginatedDecisionsTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ final class LoadPaginatedDecisionsTest extends TestCase
1010
*/
1111
public function testCanLoad10FirstDecisions(): void
1212
{
13-
//...(0, 10)
13+
// ...(0, 10)
1414
$this->markTestIncomplete('This test has not been implemented yet.');
1515
}
1616

@@ -19,7 +19,7 @@ public function testCanLoad10FirstDecisions(): void
1919
*/
2020
public function testCanLoad10LastDecisions(): void
2121
{
22-
//...(-10)
22+
// ...(-10)
2323
$this->markTestIncomplete('This test has not been implemented yet.');
2424
}
2525

@@ -28,7 +28,7 @@ public function testCanLoad10LastDecisions(): void
2828
*/
2929
public function testCanLoad5FirstDecisions(): void
3030
{
31-
//...(-10, 0)
31+
// ...(-10, 0)
3232
$this->markTestIncomplete('This test has not been implemented yet.');
3333
}
3434

@@ -37,7 +37,7 @@ public function testCanLoad5FirstDecisions(): void
3737
*/
3838
public function testCanLoadAllDecisions(): void
3939
{
40-
//...(0)
40+
// ...(0)
4141
$this->markTestIncomplete('This test has not been implemented yet.');
4242
}
4343

@@ -46,7 +46,7 @@ public function testCanLoadAllDecisions(): void
4646
*/
4747
public function testCanLoadTheSecondDecision(): void
4848
{
49-
//...(0, 2)
49+
// ...(0, 2)
5050
$this->markTestIncomplete('This test has not been implemented yet.');
5151
}
5252
}

tests/LoadPaginatedLogsTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ final class LoadPaginatedLogsTest extends TestCase
1010
*/
1111
public function testCanLoad10FirstLogInputs(): void
1212
{
13-
//...(0, 10)
13+
// ...(0, 10)
1414
$this->markTestIncomplete('This test has not been implemented yet.');
1515
}
1616

@@ -19,7 +19,7 @@ public function testCanLoad10FirstLogInputs(): void
1919
*/
2020
public function testCanLoad10LastLogInputs(): void
2121
{
22-
//...(-10)
22+
// ...(-10)
2323
$this->markTestIncomplete('This test has not been implemented yet.');
2424
}
2525

@@ -28,7 +28,7 @@ public function testCanLoad10LastLogInputs(): void
2828
*/
2929
public function testCanLoad5FirstLogInputs(): void
3030
{
31-
//...(-10, 0)
31+
// ...(-10, 0)
3232
$this->markTestIncomplete('This test has not been implemented yet.');
3333
}
3434

@@ -37,7 +37,7 @@ public function testCanLoad5FirstLogInputs(): void
3737
*/
3838
public function testCanLoadAllLogInputs(): void
3939
{
40-
//...(0)
40+
// ...(0)
4141
$this->markTestIncomplete('This test has not been implemented yet.');
4242
}
4343

@@ -46,7 +46,7 @@ public function testCanLoadAllLogInputs(): void
4646
*/
4747
public function testCanLoadTheSecondLogInput(): void
4848
{
49-
//...(0, 2)
49+
// ...(0, 2)
5050
$this->markTestIncomplete('This test has not been implemented yet.');
5151
}
5252
}

0 commit comments

Comments
 (0)