ThinkPHP文件包含漏洞核心是用户输入(如lang、cacheFile)未经校验直拼include路径,修复需切断“输入→路径→执行”链路:关闭多语言等高危模块、严格白名单校验、升级框架至安全版本(TP5.1.38+/TP6.0.13+)、禁用allow_url_include并关闭debug模式。

ThinkPHP文件包含漏洞的核心在于:用户可控输入(如 lang、cacheFile、路由参数等)未经校验,直接拼入 include/require 路径,导致本地或远程文件被非法加载执行。修复不是加一层过滤就完事,而是要切断“用户输入 → 文件路径 → 执行”这条链路。
关闭危险功能,从源头禁用风险模块
多语言模块是 QVD-2022-46174 等漏洞的高发区。若项目实际不需要多语言切换,最彻底的修复就是关掉它:
- ThinkPHP 6:在
config/app.php中将'lang_switch_on' => true改为false;同时删除或注释掉app/middleware/Lang.php中间件 - ThinkPHP 5:检查
config/lang.php,确认'support_multi' => false;并移除所有对Lang::get()或lang()的非必要调用 - 禁用所有可能触发动态包含的扩展机制,例如自定义模板缓存路径、运行时动态加载配置等
严格白名单校验所有路径拼接点
凡涉及 include、require、file_get_contents、file_exists 等函数的路径构造,必须强制使用白名单验证:
- 不接受任意字符串,只允许预设的、小写字母+短横线的固定语言标识,如
['zh-cn', 'en-us', 'ja-jp'],拒绝../../../etc/passwd、phar://、zip://等伪协议 - 对语言包路径做双重约束:
realpath($langPath)必须落在app/lang/目录内,且不能超出该目录层级(可用str_starts_with()或dirname()检查) - 模板渲染中禁止使用
$this->assign(request()->get())这类全量注入,改用显式字段赋值,如$this->assign('name', input('name/s'))
升级框架 + 关闭 PHP 危险配置
补丁和配置是双保险,缺一不可:
立即学习“PHP免费学习笔记(深入)”;
- ThinkPHP 5.x 升级至 5.0.24+ 或 5.1.38+;ThinkPHP 6.x 升级至 6.0.13+ 或 6.1.2+,这些版本已修复模板引擎中的
extract()变量覆盖、多语言路径解析绕过等问题 - 在服务器
php.ini中确保:allow_url_include = Off(禁用远程包含)、open_basedir设置为项目根目录(限制文件访问范围)、disable_functions = exec,passthru,shell_exec,system,proc_open,popen(降低RCE危害) - 生产环境禁用调试模式:
app_debug = false,避免错误信息泄露路径结构
代码层加固:用安全函数替代动态包含
不要让业务逻辑依赖“拼路径+include”,改用更可控的方式:
- 语言包统一由配置数组加载,而非
include文件,例如:$lang = config("lang.{$langCode}", []); - 模板缓存文件名由哈希生成(如
md5($template . $vars)),不暴露用户输入 - 自定义
__autoload或 Composer 自动加载时,路径全部硬编码或查表映射,杜绝外部控制



















