Stack traces in exceptions can be useful for testing and debugging purposes. The stack trace contains the function names and parameters for each stack frame. It allows seeing what data was passed to the function. However, this functionality can cause security issues. It can happen when sensitive values, such as credentials, are passed to the function.
Let's say we have a function that accepts a password parameter:
<?php
function encryptPassword(string $password): string {
throw new Exception('Error');
}
encryptPassword('pwd123');
If a function was called and something goes wrong, then an exception can be thrown. In our case, password will be visible in the stack trace:
Fatal error: Uncaught Exception: Error in main.php:4
Stack trace:
#0 main.php(7): encryptPassword('pwd123')
#1 {main}
thrown in main.php on line 4
Since PHP 8.2, the #[\SensitiveParameter]
attribute can be used to mark which function parameters shouldn't be listed in the stack trace.
<?php
function encryptPassword(#[\SensitiveParameter] string $password): string {
throw new Exception('Error');
}
encryptPassword('pwd123');
If a function was called, and it causes an exception, the parameter value passed to the function will be replaced with a SensitiveParameterValue
object.
Fatal error: Uncaught Exception: Error in main.php:4
Stack trace:
#0 main.php(7): encryptPassword(Object(SensitiveParameterValue))
#1 {main}
thrown in main.php on line 4
The #[\SensitiveParameter]
attribute can also be used to mark sensitive parameters in class methods.
<?php
class CryptoUtil
{
public static function encryptPassword(#[\SensitiveParameter] string $password): string
{
throw new Exception('Error');
}
}
Note that PHP built-in functions (e.g. password_hash
, password_verify
) has sensitive parameters that already marked with the #[\SensitiveParameter]
attribute.
<?php
password_hash('pwd123', 'unknown_algo');
Fatal error: Uncaught ValueError: password_hash(): Argument #2 ($algo) must be a valid password hashing algorithm in main.php:3
Stack trace:
#0 main.php(3): password_hash(Object(SensitiveParameterValue), 'unknown_algo')
#1 {main}
thrown in main.php on line 3
Leave a Comment
Cancel reply