ThinkPHP 6.0.12 的 lang 参数漏洞本质是路径未规范化与白名单校验缺失,导致任意文件读取甚至 RCE;修复需升级至 6.0.14+ 或手动添加 realpath+白名单校验,并禁用 register_argc_argv 等危险配置。

ThinkPHP 6.0.12 的 `lang` 参数文件包含漏洞本质是路径未规范化、缺乏白名单校验,导致攻击者可通过 `lang=../../etc/passwd` 或 `lang=../../usr/local/lib/php/pearcmd.php` 实现任意文件读取甚至远程代码执行(RCE)。修复不依赖单一手段,需组合升级、校验、配置三类措施。
确认是否真的受影响
不是所有项目都存在风险,仅当多语言功能启用时才暴露该漏洞:
- 检查 app/middleware.php 是否注册了
\think\middleware\LoadLangPack::class - 查看 config/lang.php 中
'switch' => true是否开启语言切换 - 全局搜索项目中是否有
Lang::setLangSet()或$app->lang->setLangSet()调用 - 注意第三方插件(如 FastAdmin、ThinkAdmin)可能默认启用多语言中间件
首选方案:升级到 6.0.14 或更高版本
官方已在 6.0.14 中彻底重构 LoadLangPack 行为,禁用动态路径拼接,并强制路径校验:
- 执行升级命令:
composer update topthink/framework:^6.0.14 - 升级后检查 config/lang.php 的
path配置是否指向合法目录(如app/lang/) - 确保生产环境已关闭调试:
app_debug = false和show_error_msg = false
无法升级时的手动加固
若因兼容性必须停留在 6.0.12,需在语言包加载前插入严格路径校验逻辑。不能只用 basename() 或简单字符串过滤:
- 获取原始 lang 值:
$lang = $request->param('lang', 'zh-cn'); - 构造并解析真实路径:
$baseDir = realpath(config('lang.path', app()->getAppPath() . 'lang'));$target = realpath($baseDir . DIRECTORY_SEPARATOR . $lang . '.php'); - 校验路径合法性:
if (!$target || strpos($target, $baseDir) !== 0) { throw new HttpException(400, 'Invalid lang'); } - 禁止将
$lang直接拼入include或file_get_contents
辅助加固:禁用危险 PHP 配置
即使路径校验到位,若服务器配置不当,仍可能被绕过触发 RCE:
- 在 php.ini 中设置:
register_argc_argv = Off - 限制或删除 PEAR 命令文件:
chmod 000 /usr/local/lib/php/pearcmd.php - 生产环境确保:
allow_url_include = Off,必要时在disable_functions中加入include, require, file_get_contents - 确认 Web 服务器(Nginx/Apache)不将 PHP 文件以非脚本方式解析(如静态文件下载)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











