ThinkPHP缓存漏洞修复关键在阻断“用户输入→序列化→写入PHP文件→执行”链:须净化$value(禁换行/PHP标签/危险函数)、禁用原始input直存、弃用file驱动改redis/apcu,并验证目录权限、缓存扩展名及内容安全。

ThinkPHP缓存漏洞修复不能只靠补一行str_replace,关键在阻断“用户输入→序列化→写入PHP文件→被解析执行”的攻击链。老版本(如3.2.3)的S()缓存、6.x的Cache::store('file')若未校验输入,都可能把恶意代码存成可执行的PHP缓存文件,导致RCE。
立即堵住缓存写入入口
所有调用缓存写入的地方,必须对$value做净化,禁止任何换行符、PHP标签、危险函数名:
- 在
think\cache\driver\File.php的set()方法中,serialize($value)之后、拼接"之前,加入:$data = str_replace(["\n", "\r", "", "?>", "eval(", "assert(", "system("], "", $data); - 禁用
S()接收未经处理的$_POST或input()原始值——例如S('user_data', input('raw'))必须改为S('user_data', input('raw/s', '')),强制转字符串并trim - 若项目仍用ThinkPHP 3.2.x,直接删除
Think/Cache/Driver/File.class.php中所有eval、include相关逻辑,改用Memcached或Redis驱动替代文件缓存
切换更安全的缓存驱动
文件缓存天生存在路径拼接和内容执行风险,生产环境应主动弃用:
- TP6+项目:在
config/cache.php中将'default' => 'file'改为'default' => 'redis',并配置'host'、'port'、'password' - 无Redis环境?改用
apcu(仅内存,重启即清):'type' => 'apcu',避免磁盘落地 - 绝对不推荐
xcache或eaccelerator等已废弃扩展,它们自身存在未修复的反序列化漏洞
上线前必查的三项缓存硬指标
缓存不是修完就能高枕无忧,必须验证是否真正切断攻击面:
-
检查runtime/cache/目录权限:确保Web用户(如www-data)只有
rwx,不可被其他用户读写;禁止设置777 -
确认缓存文件不带PHP扩展:升级后运行
ls runtime/cache/,若看到xxx.php文件,说明仍走旧File驱动,需检查config/cache.php是否被多环境配置覆盖 -
手动触发一次缓存写入再查看内容:用
curl -X POST -d "a=123" /index.php?s=index/test/cache调用一个写缓存接口,然后head -n 5 runtime/cache/xxx,确认输出不含、eval等关键词
业务层彻底禁用危险缓存模式
很多RCE漏洞实际来自开发者自己写的“缓存增强逻辑”,而非框架本身:
- 全局搜索
file_put_contents.*\.php、cache.*serialize、S\(.*\$_,定位所有手写缓存落盘位置 - 禁止用
include cache_path.'/'.$key.'.php'加载缓存——一律改用json_decode(file_get_contents(...), true)读取纯数据 - 多租户场景下,严禁用
tenant_id拼接缓存路径:cache/.$tenant.'/config.php'→ 改为cache/config_'.md5($tenant).'.json',杜绝目录遍历
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











