ThinkPHP 5.1.32 存在缓存相关高危风险,需重点审计Cache::set()等调用是否直接使用用户输入作键或值、文件缓存驱动是否将序列化数据写入.php文件且未过滤换行符、Cache::get()返回值是否被后续unserialize()调用,以及app_debug=true等配置是否放大攻击面。

ThinkPHP 5.1.32 属于已知存在多个缓存相关安全风险的版本(如 CVE-2018-1002015 衍生利用、文件缓存写入 WebShell、反序列化链等),代码审计时需聚焦缓存入口、存储逻辑与执行上下文三者交界点。重点不是“有没有用缓存”,而是“缓存数据从哪来、怎么存、会不会被执行”。
查缓存写入是否接收用户输入
缓存类(Cache::set()、cache())若直接使用 input()、$_GET、$_POST、$_COOKIE 等未过滤参数作为键名或值,即构成高危路径:
- 检查所有
Cache::set($key, $value)调用,确认$key是否含用户可控字符串(如input('id')、request()->param('token')) - 特别关注
Cache::tag()的标签名是否动态拼接(如Cache::tag(input('type'))->set(...)),标签名若未白名单校验,可被用于污染缓存命名空间 - 搜索
cache(、\think\Cache::、new \think\cache\driver\等关键词,定位自定义缓存操作
审文件缓存驱动是否可被注入 PHP 代码
ThinkPHP 5.1.32 默认 type => 'file' 驱动将序列化数据写入 .php 后缀文件,且仅在开头加 // 注释——换行符(%0a、\n)可绕过,导致缓存文件被解析为 PHP 脚本:
- 打开
thinkphp/library/think/cache/driver/File.php,检查set()方法中是否对$value做了serialize()后直接写入(5.1.32 中默认无过滤) - 确认缓存目录(
runtime/cache/)是否被 Web 服务器禁止直接访问(需在 Nginx/Apache 层配置 deny 规则,仅靠框架路由无效) - 检查
config/cache.php中'data_compress' => false(默认),此时序列化内容未压缩,更易被注入恶意 payload
扫反序列化调用链是否暴露在缓存读取路径
虽缓存本身不主动反序列化,但部分业务逻辑会在取缓存后调用 unserialize()(如旧版 Session 处理、自定义反序列化解析器),形成隐式反序列化入口:
立即学习“PHP免费学习笔记(深入)”;
- 全局搜索
unserialize(、__unserialize,尤其关注Cache::get()返回值后续是否被传入该函数 - 检查是否存在类似
$data = Cache::get('xxx'); $obj = unserialize($data);的模式,这是 5.1.32 中常见漏洞放大点 - 验证是否启用了
unserialize_callback_func(php.ini 中),未设置则任何反序列化失败都会静默忽略,利于攻击者试探利用链
核缓存配置与运行环境是否放大风险
某些配置组合会显著降低攻击门槛,需逐项确认:
- app_debug => true:错误页面泄露缓存路径、类名、调用栈,极大辅助攻击者构造 payload
- route_check_cache => false(或未开启):虽不直接影响缓存安全,但说明项目未启用路由缓存优化,可能反映整体安全配置松散
-
cache prefix 为空或过于简单:如
'prefix' => ''或'tp_',易引发键名冲突或被预测(如tp_user_1→md5('user_1') = xxx→ 推导文件路径) - Redis/Memcached 驱动是否明文传输、密码硬编码、未启用 SSL,导致缓存数据中途被截获或篡改



















