ref*_*med 8 php security logging credentials php-7
考虑以下代码。如果发生异常,跟踪(将被记录并存储在数据库中)将包括敏感password数据。在这种情况下,如何隐藏敏感数据,同时允许其他非敏感参数?
<?php
$user = 'john';
$pass = 'secret';
function auth($user, $pass) {
// authentication logic
}
function login($user, $pass) {
throw new Exception('Unexpected error');
// various logic
auth($user, $pass);
// various logic
}
try {
login($user, $pass);
} catch (Throwable $e) {
send_to_log($e->getTrace()); // This reveals the password "secret"
}
Run Code Online (Sandbox Code Playgroud)
小智 15
从 PHP 版本 8.2(2022 年 12 月)开始,有一个名为“编辑回溯中的参数”的功能。这将从 PHP 应用程序中的任何堆栈跟踪中隐藏该参数。
以下是该 RFC中的示例:
<?php
function test(
$foo,
#[\SensitiveParameter] $bar,
$baz
) {
throw new \Exception('Error');
}
test('foo', 'bar', 'baz');
/*
Fatal error: Uncaught Exception: Error in test.php:8
Stack trace:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
thrown in test.php on line 8
*/
Run Code Online (Sandbox Code Playgroud)
免责声明:我(有点)假设您从未真正将结果通过管道var_dump返回给您的用户。很明显(再一次),最终用户很少关心引擎的内部结构,因此向他们显示跟踪路由几乎从来都不是处理服务器错误的好方法。但你是对的;由于各种原因,即使记录这些信息实际上也可能不是一个好主意。
因此,回答最初的问题:好吧,您可以强制异常日志记录完全丢弃参数 - 或限制它们的长度:
请注意,PHP 7.4 引入了设置
zend.exception_ignore_args,它允许从异常中完全删除参数信息(在getTrace()、getTraceAsString()等中)。
设置
zend.exception_string_param_max_len=0仍然提供比完全禁用跟踪参数更多的信息(您仍然知道参数是字符串和非字符串类型)。
但这可能会使其他情况的调试变得复杂。PHP 8.0 通过引入zend.exception_string_param_max_len 配置参数在一定程度上缓解了这一问题:
zend.exception_string_param_max_len 是一个新的 INI 指令,用于设置字符串化堆栈跟踪的参数中的最大字符串长度。
这背后的想法(上面引用的)除其他外,是在记录异常时限制可能暴露的敏感数据的数量,而不会实际损害调试问题所需的数据。
请注意,此设置仅影响getTraceAsString()结果(无论如何,您应该考虑使用结果而不是 getTrace 的 var_dumping 结果)。