Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Upgrade Guide

## Version 1.2 to 1.3

### JWT: Minimum Key Length Now Enforced

If you use the JWT authenticator with an HMAC algorithm (`HS256`, `HS384`, or
`HS512`), the underlying `firebase/php-jwt` library was upgraded to v7, which
now enforces minimum key lengths at runtime.

| Algorithm | Minimum secret length | Command to generate |
|-----------|-----------------------|---------------------------------------------------|
| HS256 | 32 bytes (256 bits) | `php -r 'echo base64_encode(random_bytes(32));'` |
| HS384 | 48 bytes (384 bits) | `php -r 'echo base64_encode(random_bytes(48));'` |
| HS512 | 64 bytes (512 bits) | `php -r 'echo base64_encode(random_bytes(64));'` |

If your secret is too short, every JWT encode **and** decode call will throw a
`LogicException` with the message `Cannot encode/decode JWT: Provided key is too short`.

Run the command for your algorithm, then update `$keys` in **app/Config/AuthJWT.php**:

```php
'secret' => '<output of the command above>',
```

> [!NOTE]
> Existing tokens signed with the old short secret will become unverifiable once
> the secret is replaced. Users will need to re-authenticate to obtain new tokens.

## Version 1.0.0-beta.8 to 1.0.0

## Removed Deprecated Items
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"codeigniter/phpstan-codeigniter": "^1.3",
"codeigniter4/devkit": "^1.3",
"codeigniter4/framework": ">=4.3.5 <4.5.0 || ^4.5.1",
"firebase/php-jwt": "^6.4",
"firebase/php-jwt": "^7.0.3",
"mikey179/vfsstream": "^1.6.7",
"mockery/mockery": "^1.0",
"phpstan/phpstan-strict-rules": "^2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/Config/AuthJWT.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class AuthJWT extends BaseConfig
[
'kid' => '', // Key ID. Optional if you have only one key.
'alg' => 'HS256', // algorithm.
// Set secret random string. Needs at least 256 bits for HS256 algorithm.
// Set secret random string. Needs at least 256/384/512 bits for HS256/HS384/HS512.
// E.g., $ php -r 'echo base64_encode(random_bytes(32));'
'secret' => '<Set secret random string>',
],
Expand Down
8 changes: 4 additions & 4 deletions tests/Unit/Authentication/JWT/JWTManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ public function testParseCanDecodeTokenSignedByOldKey(): void
[
'kid' => 'Key01',
'alg' => 'HS256', // algorithm.
'secret' => 'Key01_Secret',
'secret' => 'Key01_Secret_at_least_256_bits!!',
],
];

Expand All @@ -289,12 +289,12 @@ public function testParseCanDecodeTokenSignedByOldKey(): void
[
'kid' => 'Key02',
'alg' => 'HS256', // algorithm.
'secret' => 'Key02_Secret',
'secret' => 'Key02_Secret_at_least_256_bits!!',
],
[
'kid' => 'Key01',
'alg' => 'HS256', // algorithm.
'secret' => 'Key01_Secret',
'secret' => 'Key01_Secret_at_least_256_bits!!',
],
];

Expand All @@ -311,7 +311,7 @@ public function testParseCanSpecifyKey(): void
[
'kid' => 'Key01',
'alg' => 'HS256', // algorithm.
'secret' => 'Key01_Secret',
'secret' => 'Key01_Secret_at_least_256_bits!!',
],
];

Expand Down
5 changes: 5 additions & 0 deletions tests/_support/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@ protected function setUp(): void
$config = config('Security');
$config->csrfProtection = 'session';
Factories::injectMock('config', 'Security', $config);

// Set a valid JWT secret (>= 256 bits for HS256) required by firebase/php-jwt v7
$config = config('AuthJWT');
$config->keys['default'][0]['secret'] = 'a-very-secure-secret-key-for-hs256-ok';
Factories::injectMock('config', 'AuthJWT', $config);
}
}
Loading