From 3f3e737e2cc4e03a8e5f7c6bffcb452c7a7c2a44 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sat, 19 Sep 2026 21:25:56 +0200 Subject: [PATCH] ext/openssl: scrub symmetric key material before freeing 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. --- ext/openssl/openssl_backend_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 8adf1ac813f1..2ebee973ff86 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) {