ThinkPHP 6.0.11存在任意文件写入漏洞,因用户输入未校验即参与路径拼接或内容写入,可导致Getshell;修复需切断输入与文件系统直接映射,落实路径白名单、内容过滤与权限隔离。

ThinkPHP 6.0.11 存在任意文件写入漏洞,本质是用户可控输入未校验即参与文件路径拼接或内容写入操作,常见于日志记录、缓存生成、模板渲染、配置导出、附件保存等模块。该漏洞不依赖反序列化,而是直接通过构造恶意参数(如 ?filename=../etc/passwd 或 ?content=)触发 file_put_contents()、file_get_contents()、fopen() 等函数,导致攻击者可覆盖关键文件(如 .htaccess、index.php、shell.php),进而 Getshell。
修补核心原则:切断用户输入与文件系统操作的直接映射,强制路径白名单 + 内容过滤 + 权限隔离。
一、定位并清理高危文件操作点
全项目搜索以下关键词,逐个审查:
file_put_contents(file_get_contents(-
fopen(、fwrite(、fputs( -
copy(、rename(、unlink( -
->write(、->save((尤其在thinkFile、thinkacadeLog、自定义导出类中)
重点关注:
- 日志写入方法(如
Log::write()若接受$file参数且未限制路径) - 模板导出/下载功能(如
exportTemplate()接收filename参数) - 缓存写入逻辑(如
Cache::set('key', $data, $ttl)若$data含用户可控路径) - 第三方插件中的
upload()、saveAs()方法
✅ 修复动作:
- 删除所有将
input('xxx')、$request->param('xxx')直接拼入文件路径或内容的操作; - 替换为预设安全路径 + 哈希命名(如
runtime/export/+md5($user_id . $timestamp) . '.xlsx'); - 若必须由用户指定文件名,仅允许字母、数字、下划线、短横线,并强制添加固定后缀(如
.pdf),禁止..、/、:、\等字符。
二、严格约束文件写入路径与权限
避免使用相对路径或用户拼接路径,统一走框架安全目录:
// ❌ 危险示例
$filename = input('filename');
file_put_contents('./uploads/' . $filename, $content);
// ✅ 安全写法
$allowed_exts = ['pdf', 'xlsx', 'csv'];
$ext = pathinfo(input('filetype'), PATHINFO_EXTENSION);
if (!in_array($ext, $allowed_exts)) {
throw new Exception('Unsupported file type');
}
$safe_name = uniqid('export_') . '.' . $ext;
$full_path = runtime_path() . 'export/' . $safe_name; // 使用 thinkacadeApp::getRuntimePath()
file_put_contents($full_path, $content);
⚠️ 注意:
-
runtime_path()返回的是框架运行时目录(如runtime/),应设为 Web不可访问(Nginx/Apache 配置中禁止location /runtime/访问); - 确保该目录属主为 Web 进程用户(如
www-data),权限为750,禁止写入public/、app/、config/等敏感目录。
三、禁用危险函数(生产环境强制)
在 php.ini 中禁用高风险函数(不影响 ThinkPHP 正常运行):
disable_functions = file_put_contents, file_get_contents, fopen, fwrite, copy, rename, unlink, exec, system, shell_exec, passthru, proc_open, pcntl_exec
⚠️ 若业务确需
file_put_contents(如日志),保留它,但必须配合前两步做输入净化和路径锁定。禁用exec类函数可阻断后续 RCE 链。
四、启用框架内置防护机制
ThinkPHP 6.x 提供基础防护能力,需主动开启:
-
关闭调试模式(
app_debug = false):防止错误信息泄露路径结构; -
设置
default_return_type = 'json':减少模板引擎被滥用风险; -
重写
thinkacadeLog的 write 方法,禁止日志中写入用户原始输入(尤其是$_SERVER、$_GET全量 dump); - 对所有上传接口,强制使用
thinkFile的validate()方法校验类型、大小、MIME 和后缀三重一致:
$file = request()->file('upload');
$result = $file->validate(['size'=>1024*1024,'ext'=>'jpg,png,gif'])->move(UPLOAD_PATH);
五、升级替代方案(终极建议)
ThinkPHP 6.0.11 属于早期 6.0 分支,官方已停止维护(6.0.x 最后版本为 6.0.13,且仍存在 CVE-2022-45982 等未完全修复风险)。
✅ 强烈建议升级至 ThinkPHP 6.3+(2026年10月最新稳定版为 6.3.5),其默认:
- 移除所有不安全的
unserialize()调用; - Redis/File 缓存驱动默认
serialize = false; - 日志写入路径硬编码为
runtime/log/,不可配置; - 文件上传组件默认开启
deny_php = true(自动拦截含 PHP 标签的内容)。
若无法升级,至少打上社区补丁包(如 topthink/think-safety 扩展),但不如升级彻底。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











