Category
Regression · php-src-strict · language · #[\SensitiveParameter] · pillar 4
Problem
debug_backtrace() correctly wraps #[\SensitiveParameter] args in SensitiveParameterValue, and var_dump redacts ((0) { }, no secret). But json_encode() and var_export() on the wrapper still expose the raw secret on the VM. Zend encodes an empty object / empty __set_state array.
Verified 2026-07-25 (host Zend PHP 8.2.32 vs php bin/vm.php):
| Repro |
Zend 8.2+ |
VM |
get_class($sp) |
SensitiveParameterValue |
same |
json_encode($sp) |
{} |
{"value":"secret"} |
var_export($sp) |
__set_state(array( )) |
'value' => 'secret' |
$sp->getValue() |
secret (OK) |
secret (OK) |
var_dump contains secret |
false |
false |
php-src reference
PHP implementation target
- SensitiveParameterValue implementation in
lib/ / ext/standard (or wherever the wrapper class lives) — hide backing value from json_encode / var_export / get_object_vars while keeping getValue() and __debugInfo Zend-shaped
- PHP-in-PHP; no new
runtime/*.c
Repro
./script/docker-exec.sh -- bash -lc 'cat > /tmp/spv_leak.php <<'"'"'PHP'"'"'
<?php
function f(#[\SensitiveParameter] string $password, string $user) {
return debug_backtrace();
}
$sp = f("secret", "bob")[0]["args"][0];
echo "json=", json_encode($sp), "\n";
echo "var_export=", str_replace("\n", " ", var_export($sp, true)), "\n";
PHP
php bin/vm.php /tmp/spv_leak.php
# expect json={} and empty __set_state — not "secret"'
Done when
Category
Regression· php-src-strict · language ·#[\SensitiveParameter]· pillar 4Problem
debug_backtrace()correctly wraps#[\SensitiveParameter]args inSensitiveParameterValue, andvar_dumpredacts ((0) { }, no secret). Butjson_encode()andvar_export()on the wrapper still expose the raw secret on the VM. Zend encodes an empty object / empty__set_statearray.Verified 2026-07-25 (host Zend PHP 8.2.32 vs
php bin/vm.php):get_class($sp)SensitiveParameterValuejson_encode($sp){}{"value":"secret"}var_export($sp)__set_state(array( ))'value' => 'secret'$sp->getValue()secret(OK)secret(OK)var_dumpcontainssecretfalsefalsephp-src reference
Zend/zend_exceptions.c/ sensitive parameter value object — export/json must not expose backing storeZend/zend_builtin_functions.c—debug_backtracewraps argsPHP implementation target
lib//ext/standard(or wherever the wrapper class lives) — hide backing value fromjson_encode/var_export/get_object_varswhile keepinggetValue()and__debugInfoZend-shapedruntime/*.cRepro
Done when
json_encode($sp) === '{}'(Zend)var_export/__set_statedoes not include the secretgetValue()still returns the real value;var_dumpstill redacts.phptundertest/compliance/cases/language/(or attributes/)