From 8a80bbf021ded4b59fb33352f53fe9bf7ff8e6f1 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Thu, 30 Jul 2026 11:53:19 +0000 Subject: [PATCH 1/3] ext/curl: hide sensitive parameters to curl_setopt This makes it possible to mark parameters as sensitive at runtime. curl_setopt takes many types of parameters, of which only some are secret. This tries to hide the sensitive values in stack traces, while still showing benign values. --- Zend/zend_builtin_functions.c | 4 ++++ Zend/zend_compile.h | 1 + ext/curl/interface.c | 16 ++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 87acf073a2da..9647df40368c 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1694,6 +1694,10 @@ ZEND_FUNCTION(get_defined_constants) static bool backtrace_is_arg_sensitive(const zend_execute_data *call, uint32_t offset) { + if (call->sensitive_args & (1u << offset)) { + return true; + } + const zend_attribute *attribute = zend_get_parameter_attribute_str( call->func->common.attributes, "sensitiveparameter", diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 3d4e6f3c3f9f..1fdeefbe81d4 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -652,6 +652,7 @@ struct _zend_execute_data { zend_array *symbol_table; void **run_time_cache; /* cache op_array->run_time_cache */ zend_array *extra_named_params; + uint32_t sensitive_args; /* bitmask for args */ }; #define ZEND_CALL_HAS_THIS IS_OBJECT_EX diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 07e53dfe0f9f..3d4e0af7602a 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1625,6 +1625,22 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue CURLcode error = CURLE_OK; zend_long lval; + switch (option) { + case CURLOPT_KEYPASSWD: + case CURLOPT_PASSWORD: + case CURLOPT_PROXY_KEYPASSWD: + case CURLOPT_PROXY_TLSAUTH_PASSWORD: + case CURLOPT_PROXYPASSWORD: + case CURLOPT_PROXYUSERPWD: + case CURLOPT_SSLKEY_BLOB: + case CURLOPT_TLSAUTH_PASSWORD: + case CURLOPT_USERPWD: + case CURLOPT_XOAUTH2_BEARER: + EG(current_execute_data)->sensitive_args |= (1u << 2); + default: + // do nothing + } + switch (option) { /* Callable options */ HANDLE_CURL_OPTION_CALLABLE_PHP_CURL_USER(ch, CURLOPT_WRITE, write, PHP_CURL_STDOUT); From e3e70cc087dc6887c46786993eb118004b5a87e3 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Thu, 30 Jul 2026 13:12:24 +0000 Subject: [PATCH 2/3] Reset sensitive_args again somewhere --- Zend/zend_execute.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 91cab1b63d2a..37a3702154a8 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4453,6 +4453,7 @@ static zend_always_inline void i_init_func_execute_data(zend_op_array *op_array, #endif EX(call) = NULL; EX(return_value) = return_value; + EX(sensitive_args) = 0; /* Handle arguments */ first_extra_arg = op_array->num_args; @@ -4540,6 +4541,7 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu EX(opline) = op_array->opcodes; EX(call) = NULL; EX(return_value) = return_value; + EX(sensitive_args) = 0; if (op_array->last_var) { zend_attach_symbol_table(execute_data); From 6c62aa98fcff86e008b9c64099b149f40d1a0f76 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Thu, 30 Jul 2026 13:23:54 +0000 Subject: [PATCH 3/3] Remove useless default case --- ext/curl/interface.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 3d4e0af7602a..8c1939960404 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1637,8 +1637,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue case CURLOPT_USERPWD: case CURLOPT_XOAUTH2_BEARER: EG(current_execute_data)->sensitive_args |= (1u << 2); - default: - // do nothing } switch (option) {