CVE-2024-2408
Patch Available.
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
PHP is a general-purpose scripting language used mostly for web development. It runs behind web servers through server APIs such as Apache mod_php and PHP-FPM, and powers content management systems and frameworks such as WordPress, Drupal, Moodle and Laravel. Its openssl extension exposes OpenSSL functions to PHP code, including openssl_private_decrypt() for RSA decryption.
An Information Exposure vulnerability (CVE-2024-2408) has been identified in openssl_private_decrypt() in PHP's openssl extension, which allows a remote attacker who can submit many ciphertexts and measure response times to decrypt captured ciphertexts or forge signatures with the RSA key. PHP tracks this issue as GHSA-hh26-4ppw-5864.
Per MITRE CWE-208: Two separate operations in a product require different amounts of time to complete, in a way that is observable to an actor and reveals security-relevant information about the state of the product, such as whether a particular operation was successful or not.
This issue affects all versions of PHP before 8.1.29, PHP 8.2 before 8.2.20 and PHP 8.3 before 8.3.8, when PHP is linked against an OpenSSL library without implicit rejection.
Details
Module Info
- Product: PHP
- Affected packages:
php-src(ext/openssl) - Affected versions: <8.1.29, >=8.2.0 <8.2.20, >=8.3.0 <8.3.8 (depends on the linked OpenSSL)
- GitHub repository: https://github.com/php/php-src
- Published packages: https://www.php.net/downloads
- Package manager: N/A
- Fixed in:
- OSS PHP 8.1.29, 8.2.20, 8.3.8 (Windows builds)
- NES for PHP 5.6.1 (based on PHP 5.6.40)
- NES for PHP 7.2.1 (based on PHP 7.2.34)
- NES for PHP 7.3.1 (based on PHP 7.3.33)
- NES for PHP 7.4.1 (based on PHP 7.4.33)
- NES for PHP 8.0.1 (based on PHP 8.0.30)
Vulnerability Info
This Medium-severity vulnerability is found in the openssl extension of all PHP versions before 8.1.29, PHP 8.2 before 8.2.20 and PHP 8.3 before 8.3.8, including the End-of-Life PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4 and 8.0 release lines, when PHP is linked against an OpenSSL library without implicit rejection. The CVE record carries no CNA score; CISA-ADP scores it 5.9 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N).
openssl_private_decrypt() decrypts data with an RSA private key. Its default padding is PKCS#1 v1.5 (OPENSSL_PKCS1_PADDING), and it returns false when the padding is invalid. In PHP 8.0.30 the code reads:
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
cryptedlen = RSA_private_decrypt((int)data_len,
(unsigned char *)data,
crypttemp,
EVP_PKEY_get0_RSA(pkey),
(int)padding);
if (cryptedlen != -1) {
cryptedbuf = zend_string_alloc(cryptedlen, 0);
memcpy(ZSTR_VAL(cryptedbuf), crypttemp, cryptedlen);
successful = 1;
The time the call takes depends on whether decryption returns a message, which gives an attacker an oracle for a Bleichenbacher-style attack known as the Marvin Attack. With enough timed queries, the attacker can decrypt a captured ciphertext or forge a signature with the key. The CVE record states that the issue is resolved only when PHP uses an OpenSSL version with implicit rejection for PKCS#1 v1.5 padding, which is part of OpenSSL 3.2 and has been backported by various Linux distributions.
Exposure requires an application that decrypts attacker-supplied ciphertexts with openssl_private_decrypt() using PKCS#1 v1.5 padding and lets the attacker observe response timing. Applications that use OAEP padding (OPENSSL_PKCS1_OAEP_PADDING), or that do not decrypt untrusted RSA ciphertexts, are not affected. Whether a given build is exposed depends on the OpenSSL library it is linked against.
The upstream PHP project did not change its source code for this issue. The CVE record states that the PHP Windows builds for 8.1.29, 8.2.20, 8.3.8 and later bundle OpenSSL patches that fix it. The NES for PHP 7 release notes state that NES for PHP 7 relies on the system OpenSSL's implicit rejection where the platform provides it, and that Debian 12's OpenSSL does not provide it.
Mitigation
The PHP project publishes security fixes only for its supported release lines. PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4 and 8.0 are End-of-Life and will not receive any public updates to address this issue.
Until an upgrade is possible, use OAEP padding (OPENSSL_PKCS1_OAEP_PADDING) for RSA decryption, or link PHP against an OpenSSL library that implements implicit rejection, such as OpenSSL 3.2 or later or a distribution build with the backport.
Users of the affected components should apply one of the following mitigations:
- Upgrade to PHP 8.1.29, 8.2.20, 8.3.8, or later on Windows, or link PHP against an OpenSSL library with implicit rejection.
- Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.
Credits
- Alicja Kario (finder)