Skip to content

Commit 342a368

Browse files
authored
Merge pull request from GHSA-5hm8-vh6r-2cjq
fix: CSRF protection bypass vulnerability
2 parents c95a28e + 58686b3 commit 342a368

File tree

7 files changed

+48
-4
lines changed

7 files changed

+48
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ access for a mobile application that you build.
3535

3636
Usage of Shield requires the following:
3737

38-
- A [CodeIgniter 4](https://github.com/codeigniter4/CodeIgniter4/)-based project
38+
- A [CodeIgniter 4.2.3+](https://github.com/codeigniter4/CodeIgniter4/) based project
3939
- [Composer](https://getcomposer.org/) for package management
4040
- PHP 7.4.3+
4141

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
},
2424
"require-dev": {
2525
"codeigniter4/devkit": "^1.0",
26-
"codeigniter4/framework": "^4.1",
26+
"codeigniter4/framework": "^4.2.3",
2727
"mockery/mockery": "^1.0"
2828
},
2929
"provide": {

docs/install.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212

1313
These instructions assume that you have already [installed the CodeIgniter 4 app starter](https://codeigniter.com/user_guide/installation/installing_composer.html) as the basis for your new project, set up your `.env` file, and created a database that you can access via the Spark CLI script.
1414

15+
> **Note**
16+
> CodeIgniter Shield requires Codeigniter v4.2.3 or later.
17+
18+
> **Note**
19+
> You must set ``Config\Security::$csrfProtection`` to `'session'` (or set `security.csrfProtection = session` in your `.env` file) for security reasons, if you use Session Authenticator.
20+
1521
Installation is done through [Composer](https://getcomposer.org). The example assumes you have it installed globally.
1622
If you have it installed as a phar, or othewise you will need to adjust the way you call composer itself.
1723

src/Authentication/Authenticators/Session.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
use CodeIgniter\Shield\Entities\UserIdentity;
1616
use CodeIgniter\Shield\Exceptions\InvalidArgumentException;
1717
use CodeIgniter\Shield\Exceptions\LogicException;
18+
use CodeIgniter\Shield\Exceptions\SecurityException;
1819
use CodeIgniter\Shield\Models\LoginModel;
1920
use CodeIgniter\Shield\Models\RememberModel;
2021
use CodeIgniter\Shield\Models\UserIdentityModel;
2122
use CodeIgniter\Shield\Models\UserModel;
2223
use CodeIgniter\Shield\Result;
24+
use Config\Security;
25+
use Config\Services;
2326
use stdClass;
2427

2528
class Session implements AuthenticatorInterface
@@ -72,6 +75,25 @@ public function __construct(UserModel $provider)
7275
$this->loginModel = model(LoginModel::class);
7376
$this->rememberModel = model(RememberModel::class);
7477
$this->userIdentityModel = model(UserIdentityModel::class);
78+
79+
$this->checkSecurityConfig();
80+
}
81+
82+
/**
83+
* Checks less secure Configuration.
84+
*/
85+
private function checkSecurityConfig(): void
86+
{
87+
/** @var Security $securityConfig */
88+
$securityConfig = config('Security');
89+
90+
if ($securityConfig->csrfProtection === 'cookie') {
91+
throw new SecurityException(
92+
'Config\Security::$csrfProtection is set to \'cookie\'.'
93+
. ' Same-site attackers may bypass the CSRF protection.'
94+
. ' Please set it to \'session\'.'
95+
);
96+
}
7597
}
7698

7799
/**
@@ -567,7 +589,10 @@ public function startLogin(User $user): void
567589

568590
// Regenerate the session ID to help protect against session fixation
569591
if (ENVIRONMENT !== 'testing') {
570-
session()->regenerate();
592+
session()->regenerate(true);
593+
594+
// Regenerate CSRF token even if `security.regenerate = false`.
595+
Services::security()->generateHash();
571596
}
572597

573598
// Let the session know we're logged in
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace CodeIgniter\Shield\Exceptions;
4+
5+
use RuntimeException;
6+
7+
class SecurityException extends RuntimeException
8+
{
9+
}

tests/Controllers/RegisterTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ protected function setUp(): void
3030
parent::setUp();
3131

3232
helper('auth');
33-
Factories::reset();
3433

3534
// Add auth routes
3635
$routes = service('routes');

tests/_support/TestCase.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,10 @@ protected function setUp(): void
3333
$config = config('Auth');
3434
$config->actions = ['login' => null, 'register' => null];
3535
Factories::injectMock('config', 'Auth', $config);
36+
37+
// Set Config\Security::$csrfProtection to 'session'
38+
$config = config('Security');
39+
$config->csrfProtection = 'session';
40+
Factories::injectMock('config', 'Security', $config);
3641
}
3742
}

0 commit comments

Comments
 (0)