cockpithq/cockpit:core-2.13.47fe563023b7fae854c857d2e2dc0878ef28fbb5f(标签 2.13.4)CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N在 Cockpit CMS(核心版 2.13.4)中发现了 SQL 注入漏洞。该漏洞存在于 MongoLite 聚合优化器中,具体位于 toJsonExtractRaw() 方法内。用户可控的字段名未经适当清理便直接拼接进 SQL 查询中。
拥有内容模型读取权限(通过 API 密钥)的已认证攻击者可以通过 /api/content/aggregate/{model} REST 端点向聚合管道注入任意 SQL 命令。
此缺陷使攻击者能够:
_state=1)以读取未发布的草稿。sqlite_master 枚举内部数据库架构。以下步骤演示了攻击者如何绕过 _state=1 授权过滤器。
testcol 的新模型。title 和 body。截图:设置 testcol 内容模型

MasterRole),使其对 testcol 模型拥有 读取 权限。截图:为集合配置角色权限

MasterRole。复制密钥值(例如 API-b8e8...)。截图:设置具有读取访问角色的 API 密钥

Public 的项目,并将其状态设置为已发布(绿色图标)。SECRET_DRAFT 的项目,并将其状态设置为未发布(红色图标)。截图:显示一个已发布和一个未发布项目的列表

默认情况下,标准 API 查询只会返回状态为已发布的内容。然而,通过向聚合管道注入 SQL,可以绕过已发布内容过滤器。
json_extract() SQL 函数,并附加一个 SQL 注释 -- 来中和尾随的 SQL,专门针对将结果限制为已发布项目的 WHERE 子句。注入字段:
$title') as _id FROM collections_testcol--
完整管道 JSON:
[{"$group": {"_id": "$title') as _id FROM collections_testcol--", "c": {"$sum": 1}}}]
/api/content/aggregate/testcol 端点发送 GET 请求。确保将 YOUR_API_KEY 替换为在步骤 2.2 中生成的密钥:curl "http://localhost:8080/api/content/aggregate/testcol?api_key=YOUR_API_KEY&pipeline=%5B%7B%22%24group%22%3A%20%7B%22_id%22%3A%20%22%24title%27%29%20as%20_id%20FROM%20collections_testcol--%22%2C%20%22c%22%3A%20%7B%22%24sum%22%3A%201%7D%7D%7D%5D"
如下方最终截图所示,API 响应成功返回了 SECRET_DRAFT 项目,尽管它被明确标记为未发布。这证实了 SQL 注入绕过了应用程序的核心授权机制,并允许通过 API 进行未经授权的数据提取。
截图:成功提取未发布的 'SECRET_DRAFT' 数据

在典型的无头 CMS 部署中,公共只读 API 密钥通常被嵌入/硬编码在前端 JavaScript 中。通过利用此漏洞经由公共 API 端点,攻击者可以:
content.sqlite 数据库中的所有内容集合,包括 API 密钥未被授权的集合。sqlite_master 枚举数据库架构,以发现所有表名和结构。| 日期 | 操作 |
|---|---|
| 2026-02-28 | 在授权安全研究期间发现漏洞 |
| 2026-03-02 | 向供应商提交报告 |
| 2026-03-02 | 供应商修复 -- https://github.com/Cockpit-HQ/Cockpit/commit/b6a0b45c5e8fe16f3027b889583cc3a9127ab4b0 |
| 2026-03-09 | 发布补丁 v 2.13.5 -- https://getcockpit.com/releases |