Security context
MediumGHSA-7852-w36x-6mf6 CWE-1240Published May 15, 2024

Laravel Encrypter Component Potential Decryption Failure Leading to Unintended Behavior

Research this vulnerability

Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.

Affected versions

0 → fixed in 5.5.405.6.0 → fixed in 5.6.15

Details

The Laravel Encrypter component is susceptible to a vulnerability that may result in decryption failure, leading to an unexpected return of `false`. Exploiting this issue requires the attacker to manipulate the encrypted payload before decryption. When combined with weak type comparisons in the application's code, such as the example below: ``` <?php $decyptedValue = decrypt($secret); if ($decryptedValue == '') { // Code is run even though decrypted value is false... } ```

The fix

check iv length

Taylor Otwell· Mar 30, 2018, 01:26 PM+2328e53f23a7
src/Illuminate/Encryption/Encrypter.php+2 3
@@ -206,9 +206,8 @@ protected function getJsonPayload($payload)
*/
protected function validPayload($payload)
{
- return is_array($payload) && isset(
- $payload['iv'], $payload['value'], $payload['mac']
- );
+ return is_array($payload) && isset($payload['iv'], $payload['value'], $payload['mac']) &&
+ strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length($this->cipher);
}
/**

check iv length

Taylor Otwell· Mar 30, 2018, 01:24 PM+173886d261df0
src/Illuminate/Encryption/Encrypter.php+2 3
@@ -206,9 +206,8 @@ protected function getJsonPayload($payload)
*/
protected function validPayload($payload)
{
- return is_array($payload) && isset(
- $payload['iv'], $payload['value'], $payload['mac']
- );
+ return is_array($payload) && isset($payload['iv'], $payload['value'], $payload['mac']) &&
+ strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length($this->cipher);
}
/**
tests/Encryption/EncrypterTest.php+15 0
@@ -102,4 +102,19 @@ public function testExceptionThrownWithDifferentKey()
$b = new Encrypter(str_repeat('b', 16));
$b->decrypt($a->encrypt('baz'));
}
+
+ /**
+ * @expectedException \Illuminate\Contracts\Encryption\DecryptException
+ * @expectedExceptionMessage The payload is invalid.
+ */
+ public function testExceptionThrownWhenIvIsTooLong()
+ {
+ $e = new Encrypter(str_repeat('a', 16));
+ $payload = $e->encrypt('foo');
+ $data = json_decode(base64_decode($payload), true);
+ $data['iv'] .= $data['value'][0];
+ $data['value'] = substr($data['value'], 1);
+ $modified_payload = base64_encode(json_encode($data));
+ $e->decrypt($modified_payload);
+ }
}

References