Commit 5188744ef76 for php.net
commit 5188744ef76b01b54474c881a536b5dfbc1492f6
Author: Julien Voisin <jvoisin@users.noreply.github.com>
Date: Sun Sep 20 14:21:08 2026 +0200
ext/openssl: scrub symmetric key material before freeing (#23778)
When the supplied key is shorter than the cipher's key length,
php_openssl_cipher_init() allocates a heap buffer, copies the key into
it and zero-pads it to the required length. openssl_encrypt() and
openssl_decrypt() then efree() this buffer without wiping it, leaving
the raw symmetric key in a reclaimed heap chunk where it can later be
exposed through an uninitialized-heap read, a core dump or /proc.
Scrub the buffer with ZEND_SECURE_ZERO() before freeing it, matching
what ext/hash, ext/standard/crypt* and ext/sodium already do for key
material. At the free site password_len has already been set to the
full allocation size, so the whole buffer is cleared.
diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c
index 8adf1ac813f..2ebee973ff8 100644
--- a/ext/openssl/openssl_backend_common.c
+++ b/ext/openssl/openssl_backend_common.c
@@ -1974,6 +1974,8 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt(
}
if (free_password) {
+ /* password points at a heap copy of the symmetric key; scrub it before freeing */
+ ZEND_SECURE_ZERO((void *) password, password_len);
efree((void *) password);
}
if (free_iv) {
@@ -2052,6 +2054,8 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt(
}
if (free_password) {
+ /* password points at a heap copy of the symmetric key; scrub it before freeing */
+ ZEND_SECURE_ZERO((void *) password, password_len);
efree((void *) password);
}
if (free_iv) {