-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
PHP Version
8.3
CodeIgniter4 Version
4.6.4
CodeIgniter4 Installation Method
Composer (using codeigniter4/appstarter)
Which operating systems have you tested for this bug?
Windows
Which server did you use?
apache
Environment
development
Database
MySQL
What happened?
When Encryption::$driver is set to Sodium, CodeIgniter’s Encrypter service becomes unusable within the same request after the first encryption/decryption.
This happens because SodiumHandler securely wipes the key using sodium_memzero(), but the Encrypter service is shared (singleton) and the key is not reloaded, causing subsequent calls to fail.
This issue becomes critical when Sessions are enabled, because the Session system internally uses the shared Encrypter.
Steps to Reproduce
Set Sodium as the global encryption driver:
// Config/Encryption.php
public string $driver = 'Sodium';
Set a valid Sodium key:
encryption.key = <base64-encoded 32-byte key>
Enable sessions (default setup).
In a controller (e.g. login flow), perform two encryption operations in the same request:
One implicitly via Session
One explicitly via Services::encrypter()->encrypt()
Example:
$session->set('foo', 'bar'); // internally uses encrypter
Services::encrypter()->encrypt('test');
Actual Result
A runtime exception is thrown on the second encryption:
SodiumException: sodium_crypto_secretbox(): Argument #3 ($key) must be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long
Stack trace points to:
CodeIgniter\Encryption\Handlers\SodiumHandler::encrypt()
Expected Output
Multiple encryption/decryption operations should work safely in the same request.
Sodium should be usable as a supported global encryption driver without breaking Sessions or subsequent calls.
Anything else?
SodiumHandler correctly wipes the key after use: sodium_memzero($this->key);