rfc:exception_ignore_args_default_value

PHP RFC: Change default zend.exception_ignore_args INI setting

Introduction

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
  • The default exception and error handler

Proposal

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.

Why existing features are insufficient

Changing the ''display_errors'' INI setting

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.

Proper configuration of a framework's error handler

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.

#[\SensitiveParameter]

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}
*/

Backward Incompatible Changes

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.

Proposed PHP Version(s)

Next minor version, i.e. PHP 8.5.0.

RFC Impact

php.ini Defaults

This RFC proposes changing:

  • the default INI value for zend.exception_ignore_args to On
  • the php.ini-development value of zend.exception_ignore_args to On
  • the php.ini-production value of zend.exception_ignore_args to On

To SAPIs

None.

To Existing Extensions

None.

To Opcache

None.

New Constants

None.

Unaffected PHP Functionality

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.

Future Scope

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:

  • a new constant is introduced to allow developers to explicitly include arguments in stack traces for these calls
  • the default behaviour changes to follow the 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.

Proposed Voting Choices

(Each child vote result will be considered only if its parent vote passes.)

  • Change the default value of zend.exception_ignore_args to On: Simple vote (Yes / No), requiring a 2/3 majority to pass.
    • Change the suggested value in the 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)

Patches and Tests

A patch-set has been created which implements both of the proposed changes.

Implementation

After the project is implemented, this section should contain

  • the version(s) it was merged into
  • a link to the git commit(s)
  • a link to the PHP manual entry for the feature
  • a link to the language specification section (if any)

References

Rejected Features

rfc/exception_ignore_args_default_value.txt · Last modified: by andrewlyons