ThinkPHP 6.0 默认不自动过滤日志敏感字段,防护关键是在写入前拦截——需重写 File 日志驱动 write() 方法递归过滤 password、token 等键名并替换为 [filtered],同时关闭 log_bind、禁用 log_request_data、关闭调试模式,并禁止 runtime/log/ Web 访问。

ThinkPHP 6.0 默认不会自动过滤日志中的敏感字段(如密码、token、手机号、数据库连接串等),一旦开启调试或错误日志,这些信息可能明文写入 runtime/log/ 下的文件,被攻击者通过 URL 直接读取。防护关键在于「不让敏感内容进日志」,而非事后脱敏。
在日志写入前拦截敏感键名
TP6 使用 PSR-3 兼容的日志系统,可通过自定义日志处理器(Handler)实现字段过滤。推荐在 app/common.php 或日志配置中注册一个包装器:
- 重写
think\log\driver\File的write()方法,在序列化或拼接日志消息前,递归扫描$data(如异常上下文、请求参数、SQL 绑定值) - 对常见敏感键名(
password、pwd、token、access_token、secret、key、card_no、id_card等)做模糊匹配并替换为[filtered] - 注意:需同时处理数组深层嵌套和 JSON 字符串内的敏感字段(如 SQL 日志中
"params": {"pwd":"123"})
禁用高危日志来源
有些日志条目天生携带大量敏感信息,应优先关闭:
- 关闭 SQL 绑定参数日志:在
config/database.php中设'log_bind' => false,避免VALUES (?, ?)后面跟着真实值被记录 - 禁止记录完整请求体:确保
config/app.php中'log_request_data' => false(TP6.0 默认为false,但部分项目会手动开启) - 调试模式下堆栈中常含环境变量(如
DB_PASSWORD),必须保证app_debug = false,且.env中无APP_DEBUG=true
限制日志目录可访问性
即使做了字段过滤,也需防止日志文件被 Web 直接读取:
- Nginx 配置中明确禁止访问
runtime/log/路径:
location ^~ /runtime/log/ { deny all; } - Apache 下在
runtime/.htaccess中添加:
Deny from all - 确保
runtime/目录权限为750,属主为 PHP 进程用户,非 Web 用户不可读
用中间件预清洗请求上下文
很多敏感字段来自请求参数(如登录接口提交的 password),可在日志记录前就从上下文中剥离:
- 新建中间件
app/middleware/CleanLogContext.php - 在
handle()中调用$request->filter(['password', 'token'])或手动 unset 相关参数 - 将清洗后的
$request传入后续流程,确保think\Log::record()获取的是净化后数据
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











