thinkphp 8.0+高频漏洞仍存:反序列化链未断(validate类__call可触发rce)、路由变量未约束致路径遍历、多应用session配置失效引发越权、软删除缓存键缺失delete_time字段、cors credentials与*通配符冲突。

ThinkPHP 8.0 新版(含 8.0.x 至 8.1.0)虽已大幅强化安全机制,但实际项目中仍存在几类高频、隐蔽且易被忽视的漏洞点,不及时处理可能引发 RCE、会话劫持或数据泄露。重点不是“有没有漏洞”,而是哪些漏洞在升级后仍因配置或使用不当而持续生效。
反序列化链未完全切断,Validate 类仍是高危入口
8.0.0 初始版本中 think\Validate 的 __call() 方法可被构造恶意参数触发 call_user_func_array,配合可控 $this->type 数组执行任意函数。虽 8.0.3+ 已对 type 字段加了白名单校验,但若项目手动扩展了验证规则并动态注册了危险回调(如 ['shell_exec' => 'shell_exec']),该链仍可复现。
- 检查所有自定义验证器类,禁止将用户输入直接赋值给
$validate->type[$rule] - 确认
vendor/topthink/framework/src/think/Validate.php中__call()方法内是否保留isset($this->type[$rule])且未做in_array($rule, $safeRules)校验 - 若用到了
rule => ['is' => 'xxx']这类动态规则,需确保xxx是预定义安全方法名,而非拼接字符串
路由变量未约束导致路径遍历与注入穿透
ThinkPHP 8.0 默认允许 :id 匹配任意字符(包括 ../、%2e%2e%2f),若控制器中直接拼接路径(如 file_get_contents('./data/' . $id . '.json')),就构成路径遍历。更隐蔽的是:当路由定义为 Route::get('api/:version/:action', ...) 且未限制 :version 时,攻击者传入 v1.5%00 可绕过后续正则校验,触发空字节截断或 JSON 解析异常。
- 所有含变量的路由必须显式加正则约束:
':version([a-z0-9._]+)'、':action([a-zA-Z]+)' - 避免在业务逻辑中直接拼接用户可控路由变量到文件路径、SQL 字段名或 shell 命令中
- 启用
config/route.php中的'url_domain_deploy' => true,防止子域名污染主路由上下文
多应用 Session 共享配置失效引发越权登录
8.0 多应用模式下,若 config/session.php 中 cookie_domain 写成 example.com(缺前置点)或 www.example.com(限死单域名),浏览器不会向 admin.example.com 发送 Cookie;更严重的是,若 Redis 存储未设统一 prefix,www 应用写入的 session 数据会被 api 应用读取失败,框架自动新建 session,导致用户登录态丢失——此时前端常重试登录,反而暴露账号密码。
-
cookie_domain必须为.example.com(带前导点) -
prefix必须为空字符串或全站一致(如'sess_'),不能是'www_sess_'和'api_sess_'混用 - 在
app/middleware.php中确认\think\middleware\SessionInit::class已启用且位于数组首位
模型缓存键未包含软删除字段,导致逻辑删除数据仍返回
启用 cache() 查询时,若缓存键未纳入 delete_time 字段,软删除后的记录仍从缓存中读出,用户看到已被“删除”的敏感信息。例如:UserModel::where('status', 1)->cache(['user_list'], 3600)->select(),当某条记录 later 被 delete(),缓存不变,接口持续返回该记录。
- 所有涉及软删除模型的缓存键,必须显式包含
delete_time值:cache(['user_list', $status, $user->delete_time ?? 0], 3600) - 或改用
withTrashed()+ 缓存,但需同步调整业务逻辑判断
CORS 配置中 credentials 与通配符 Origin 同时启用'allowed_origins' => ['*'] 与 'supports_credentials' => true 并存时,浏览器直接拒绝响应(违反 CORS 规范),前端报错 The value of the 'Access-Control-Allow-Origin' header must not be the wildcard '*' when the request's credentials mode is 'include'。这不是 ThinkPHP 的 bug,而是配置冲突。
- 若前端带 Cookie 请求(
credentials: 'include'),allowed_origins必须为具体域名数组,不可含* - 开发环境可临时用
$_SERVER['HTTP_ORIGIN']动态匹配白名单,但生产环境必须硬编码可信源
这些漏洞大多不源于框架代码本身,而来自配置疏漏、开发习惯或旧项目迁移遗留。修复成本不高,但一旦触发,影响直接且难以追溯。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











