注意:在公开发布前已负责任地向Cockpit CMS维护者披露并已被修复。
| CVE ID | CVE-2026-39275 |
| 漏洞类型 | 存储型跨站脚本 (XSS) → 账户接管 |
| CWE | CWE-79 |
| 受影响版本 | Cockpit CMS <= 2.13.5 |
| 已修复版本 | d70dc50 |
| CVSS 3.1 | 8.4 (AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N) |
| 报告者 | Rohith - SecurifyAI 安全顾问 |
内容集合列表视图中存在一个存储型XSS漏洞,允许任何具有内容写入权限的用户(API密钥或经过身份验证的编辑器会话)注入任意JavaScript代码,该代码会在查看受影响集合项目列表的任何管理员或编辑器的浏览器中执行。
Cockpit的会话令牌完全可以从JavaScript访问 - 会话cookie在设置时未使用HttpOnly标志,并且CSRF JWT暴露在全局变量App.csrf和<html>的data-csrf属性中。这使得注入的脚本能够读取这两个令牌并在外部重放它们,从而绕过CSRF保护,实现完全的会话劫持和账户接管。
字段 render() 的输出被传递到Vue的 v-html 指令,而未进行输出编码。
| 文件 | 行号 |
|---|
curl -X POST "http://localhost:8080/api/content/item/posts" \
-H "Content-Type: application/json" \
-H "api-key: USR-<attacker-api-key>" \
-d '{
"data": {
"title": "Innocent Looking Post",
"tags": [
"",
""
],
"body": "Just a regular post.",
"_state": 1
}
}'
管理员或编辑器导航到 /content/collection/items/posts。标签渲染器返回存储的字符串,v-html 将其解析为真实的 `` 元素,伪造的 src 失败,从而触发 onerror 处理程序。
现在两个令牌都可读——通过 document.cookie 读取会话cookie,通过 App.csrf / document.documentElement.getAttribute('data-csrf') 读取CSRF JWT。武器化的payload将两者外泄:
攻击者重放窃取的cookie和CSRF令牌,获得完全经过身份验证的管理员访问权限——然后可以创建管理员帐户、更改凭据或修改内容。
低权限编辑器(或任何内容写入API密钥持有者)可以升级为完全管理员。payload被存储,并在每个查看列表的管理员/编辑器处触发,构成持久性、多受害者的沦陷。
主要修复 - 在渲染输出到达 v-html 之前,使用现有的 App.utils.stripTags() 辅助函数进行清理。
field-tags.js:
value = App.utils.stripTags(value); // sanitize before v-html
field-select.js:
return App.utils.stripTags(value); // sanitize before v-html
纵深防御 - 强化会话cookie:
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1); // over HTTPS
ini_set('session.cookie_samesite', 'Strict');
仅使用 HttpOnly 是不够的——XSS仍然可以在受害者的已认证浏览器上下文中运行——因此输出编码是必要的修复措施。
| 日期 | 事件 |
|---|---|
| 2026-03-29 | 漏洞报告给Cockpit CMS维护者 |
| 2026-03-29 | 维护者发布修复 |
| 2026-04-04 | 请求CVE |
本材料在协调披露后出于教育和防御目的发布。仅可用于您拥有的或明确授权测试的系统。
| 角色 |
|---|
modules/App/assets/vue-components/fields/field-tags.js | 25 - 34 | 标签渲染器 - 无编码 |
modules/App/assets/vue-components/fields/field-select.js | 26 | 选择渲染器 - 无编码 |
modules/Content/views/collection/items.php | 149 | v-html 接收点 |
| 2026-06-23 | 分配CVE-2026-39275 |
<pub date> | 公开发布 |