The zend.exception_ignore_args
INI setting was introduced in PHP 7.4.0 and allows arguments to be excluded from stack traces generated for exceptions.
When the INI setting was introduced the value suggested for Production environments was On
(arguments excluded). However this is only a /suggestion/ and both the default value, and the developer-suggested value, were left at Off
(arguments included).
The intention of this RFC Proposal is to make the language safer by default and reduce the risk of unintended information disclosure. This is achieved by changing the default value of the setting to be On
, thereby removing arguments from typical stack traces.
The value of this INI setting impacts the way that exceptions are displayed in several locations, including:
Throwable::getTrace()
Throwable::getTraceAsString()
Exception::$trace
Error::$trace
Change the default value of the INI setting to On
, meaning that arguments are excluded from stack traces by default.
I believe these changes are both pragmatic and considerate of the wide range of skill levels among PHP users.
One alternative to this proposal is to disable the display of errors entirely. The default for the display_errors
INI setting could instead be modified to be Off
thereby further reducing impact. However displaying errors is often helpful when debugging an application; and logs can still be helpful, and relatively safe, without including the stacktrace arguments.
If the default for the display_errors
INI setting were changed to Off
, and an administrator re-enabled it On
in this scenario, it is still a good practice to remove arugments from the stack trace to prevent sensitive information from being displayed. If the administrator really wants to display arguments then they can also set the zend.exception_ignore_args
INI setting to Off
.
Therefore I would argue that the best option is to modify the defaults for both of these INI settings. This would provide the best default configuration for PHP, while still allowing developers to override the settings if they require them.
Changing the default value of display_errors
should probably be considered as a separate RFC.
Ideally frameworks and applications should always be correctly configured. However, mistakes happen, and PHP should provide the safest and most pragmatic default configuration, regardless of framework.
Frameworks are already able to modify the INI setting using ini_set()
if they do require these arguments, and documentatinon can guide users to update their configuration if required.
Guidance for RFCs state that:
PHP is and should remain [...] a language which caters to the skill-levels and platforms of a wide range of users.
It is important to consider that not all users are aware of the potential security implications of displaying sensitive information in stack traces. By changing the default value of this INI setting, we can help protect users from inadvertently exposing sensitive information.
A new #[\SensitiveParameter]
was introduced in PHP 8.2.0 to mask parameters in stack traces, however it has some shortcomings which make it unsuitable in many cases — notably where parameters are passed to external libraries not under your own control.
The main issue with this parameter is that it only masks the parameter at the point that it the attribute is used. A sensitive parameter does not automatically apply at any point higher or lower in the stack trace, potentially revealing sensitive information unless the entire codebase is audited for potential issues. For example:
<?php class Example { public function doSomething( #[\SensitiveParameter] $sensitive, ): void { $this->doSomethingElse($sensitive); } public function doSomethingElse( $sensitive, ): void { throw new \Exception('Something went wrong'); } } $example = new Example(); try { $example->doSomething('MySecretValue'); } catch (\Exception $e) { print_r($e->getTraceAsString()); } /* # 0 /in/ve6SG(7): Example->doSomethingElse('MySecretValue') # 1 /in/ve6SG(19): Example->doSomething(Object(SensitiveParameterValue)) # 2 {main} */
No backwards incompatible changes are expected. Any system using the stacktrace arguments must already be capable of handling both the On
, and Off
INI values.
Next minor version, i.e. PHP 8.5.0.
This RFC proposes changing:
zend.exception_ignore_args
to On
php.ini-development
value of zend.exception_ignore_args
to On
php.ini-production
value of zend.exception_ignore_args
to On
None.
None.
None.
None.
The behaviour of the following related methods will not change:
debug_backtrace()
debug_print_backtrace()
These values are not currently subject to the zend.exception_ignore_args
INI setting, and this RFC does not propose changing that. They are instead controlled by developer-defined flags passed to the $options
parameter of these methods.
As noted, this proposal does not alter the debug_backtrace()
or debug_print_backtrace()
methods. These are controlled separately using the DEBUG_BACKTRACE_IGNORE_ARGS
flag passed to their $options
parameter. However, introducing an explicit DEBUG_BACKTRACE_INCLUDE_ARGS
constant could provide greater flexibility for developers who need argument inclusion in stack traces.
If this constant were created then it would also be possible for these methods to respect the zend.exception_ignore_args
INI setting as their default state. Ideally a separate RFC would cover a multi-step change over several versions whereby:
zend.exception_ignore_args
INI setting
Another consideration may be to extend the flag(s) to the Throwable::getTrace()
and Throwable::getTraceAsString()
methods to improve consistency with debug_backtrace()
and debug_print_backtrace()
. This would allow developers to explicitly include arguments in stack traces for these calls, while still respecting the zend.exception_ignore_args
INI setting. However, this RFC does not propose any changes to these methods.
(Each child vote result will be considered only if its parent vote passes.)
zend.exception_ignore_args
to On
: Simple vote (Yes / No), requiring a 2/3 majority to pass.php.ini-development
to On
:: Simple vote (Yes / No), requiring a 2/3 majority to pass, only considered if the first vote passes.(The voting period would be two weeks)
A patch-set has been created which implements both of the proposed changes.
After the project is implemented, this section should contain