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-38361 — Avis : CVE-2026-38361 multiples vulnérabilités de déni de service (CWE-400/CWE-670) dans dash-uploader (Python/PyPI) | Kitploit
Outils/GitHubGitHub/a1ohadance/cve-2026-38361
Analyse des VulnérabilitésExploitationSécurité WebTests d'IntrusionApprentissage et Éducation
GitHuba1ohadance/cve-2026-38361

CVE-2026-38361

Avis : CVE-2026-38361 multiples vulnérabilités de déni de service (CWE-400/CWE-670) dans dash-uploader (Python/PyPI)

Voir le dépôt
il y a 3 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

CVE-2026-38361 : Multiples vulnérabilités DoS non authentifiées dans dash-uploader

CVE NVD CWE-400 CWE-670 Severity Patch Auth Version PyPI Downloads Total Downloads License

De multiples problèmes de déni de service (DoS) non authentifiés dans fohrloop/dash-uploader (Python, PyPI), incluant (sans s'y limiter) un crash du processus par manque de mémoire (OOM), une troncature de fichier à zéro octet, un épuisement permanent du disque et un contournement complet de la limite max_file_size documentée. D'autres voies d'abus de ressources existent via le même ensemble de paramètres non assainis.

⚠️ Aucun correctif n'est disponible et aucun ne sera jamais publié

Le dépôt a été archivé le 2025-07-19 sans mainteneur actif. Chaque version publiée (0.1.0 à 0.7.0a2) est concernée et le restera. Le paquet attire toujours environ 28 000 téléchargements mensuels.

Toute personne exécutant dash-uploader en production doit appliquer elle-même une mesure d'atténuation. La correction recommandée consiste à migrer vers le composant dcc.Upload intégré de Plotly Dash. Voir Atténuation pour toutes les options.

Description

Le gestionnaire HTTP de dash-uploader accepte des requêtes POST non authentifiées avec des paramètres contrôlés par l'attaquant qui alimentent l'allocation mémoire, les opérations sur fichiers et la création de répertoires, sans vérification de bornes, sans limite de débit et sans mécanisme de nettoyage. Quatre problèmes indépendants dans le même chemin de code :

1. Crash OOM (vérifié)

Vérifié sur un système de 7,7 Go : 5 requêtes POST concurrentes avec resumableTotalChunks=30000000 ont déclenché le tueur OOM de Linux en moins de 2 secondes. Le journal du noyau le confirme :

root@kitploit:~
Out of memory: Killed process 24203 (python3) total-vm:8302276kB, anon-rss:7068012kB

Chaque requête alloue environ 2,9 Go via une compréhension de liste sur range(1, resumableTotalChunks + 1). Le processus serveur est tué et l'application devient totalement indisponible jusqu'à un redémarrage manuel.

2. Troncature de fichier (vérifiée)

Un fichier contenant 42 octets de données a été réduit à 0 octet via une seule requête POST avec resumableTotalChunks=0. La cause racine est que all() de Python renvoie True pour les itérables vides, ce qui trompe le gestionnaire de téléversement en lui faisant considérer zéro fragment comme un téléversement terminé. Le fichier existant est supprimé via os.unlink() et remplacé par un fichier vide.

3. Accumulation de téléversements abandonnés (vérifiée)

10 répertoires temporaires orphelins avec des fichiers de fragments ont été créés et ont persisté indéfiniment sur le disque. Une recherche dans l'ensemble de la base de code, dans tous les fichiers source, pour cleanup, ttl, expire, garbage, purge, cron, schedule et periodic n'a renvoyé aucun résultat. Le seul appel de nettoyage (shutil.rmtree) s'exécute exclusivement lors des téléversements terminés. Il n'existe aucun mécanisme pour récupérer l'espace disque des sessions incomplètes.

4. Contournement de max_file_size (vérifié)

Le serveur a accepté un fragment de 5 Mo pour un fichier déclarant resumableTotalSize=999999999999 (~999 Go) avec un code HTTP 200. Le paramètre max_file_size n'est transmis qu'au composant JavaScript React. Le serveur ne vérifie jamais la taille du fichier, la taille des fragments, Content-Length ou MAX_CONTENT_LENGTH de Flask. Un développeur qui définit max_file_size=10 ne bénéficie d'aucune protection côté serveur.

Code vulnérable

root@kitploit:~
# dash_uploader/httprequesthandler.py
def _post(self):
    resumableTotalChunks = request.form.get("resumableTotalChunks", type=int)   # attacker-controlled, no bounds
    ...
    chunk_paths = [
        os.path.join(temp_dir, get_chunk_name(resumableFilename, x))
        for x in range(1, resumableTotalChunks + 1)                              # unbounded; e.g. 30M -> ~2.9 GB -> OOM
    ]
    upload_complete = all([os.path.exists(p) for p in chunk_paths])              # all([]) is True -> truncation when chunks=0
    if upload_complete:
        target_file_name = os.path.join(temp_root, resumableFilename)
        if os.path.exists(target_file_name):
            os.unlink(target_file_name)                                          # existing file deleted
        with open(target_file_name, "ab") as target_file:
            for p in chunk_paths:                                                # empty list -> empty file written
                ...

Le même chemin de code produit à la fois l'OOM (resumableTotalChunks élevé) et la primitive de troncature de fichier (resumableTotalChunks=0).

Vecteurs d'attaque

Un attaquant envoie des requêtes POST non authentifiées au point de terminaison /API/resumable.

  • Crash OOM : 5 requêtes concurrentes avec resumableTotalChunks=30000000 allouent ~2,9 Go chacune, déclenchant le tueur OOM.
  • Épuisement du disque : démarrer des téléversements sans jamais les terminer ; les fichiers temporaires orphelins s'accumulent indéfiniment.
  • Troncature de fichier : envoyer resumableTotalChunks=0 ; all([])=True de Python trompe le serveur en lui faisant écraser le fichier cible avec un contenu vide.
  • Contournement de taille : toute limite de taille définie par le développeur n'est appliquée que dans le JavaScript client, donc une requête HTTP directe la contourne entièrement.

Aucune authentification ni privilège requis.

Impact

  • Crash du processus serveur via le tueur OOM de Linux, déclenché par une allocation mémoire sans borne à partir d'un seul paramètre POST contrôlé par l'utilisateur (resumableTotalChunks)
  • Épuisement permanent du disque via des sessions de téléversement abandonnées qui ne sont jamais nettoyées (aucun TTL, aucun ramasse-miettes, aucun mécanisme d'expiration dans la base de code)
  • Épuisement des inodes du système de fichiers via la création de répertoires à profondeur arbitraire par os.makedirs() avec un resumableIdentifier non assaini
  • Destruction de données via la troncature de fichier à zéro octet causée par all() de Python qui renvoie True pour les itérables vides lorsque resumableTotalChunks=0
  • Contournement de toutes les restrictions de taille de fichier car max_file_size n'est appliqué que dans le JavaScript côté client, tandis que le gestionnaire côté serveur n'effectue aucune validation de taille et ne définit jamais MAX_CONTENT_LENGTH de Flask

Composants concernés

  • dash_uploader/httprequesthandler.py (méthode BaseHttpRequestHandler._post)
  • dash_uploader/upload.py (fonction Upload, paramètre max_file_size)
  • dash_uploader/configure_upload.py (MAX_CONTENT_LENGTH manquant)

Atténuation

⚠️ Aucun correctif n'est disponible et le projet est archivé

Options pour les utilisateurs actuellement en production, par ordre de préférence :

  1. Migrer vers dcc.Upload, le composant de téléversement officiel fourni avec Plotly Dash. Il n'a pas de paramètre de nombre de fragments, pas d'état temporaire sur disque, et respecte MAX_CONTENT_LENGTH de Flask. Aucun des quatre problèmes décrits ici ne s'y applique. Idéal pour les fichiers petits et moyens. Pour les très gros téléversements, voir le point 2.
  2. Développer un petit gestionnaire de téléversement Flask avec une application explicite d'une taille maximale par requête (MAX_CONTENT_LENGTH), des bornes sur tout nombre de fragments fourni par le client, et une liste blanche pour les noms de fichiers acceptés.
  3. Si vous continuez à utiliser dash-uploader, définissez MAX_CONTENT_LENGTH de Flask au niveau de l'application (la bibliothèque ne le fait pas), et rejetez les entrées au niveau de l'application ou du proxy inverse lorsque l'une des conditions suivantes est vraie :
    • resumableTotalChunks <= 0
    • resumableTotalChunks dépasse une borne raisonnable (par exemple 10 000)
    • resumableTotalSize dépasse le max_file_size configuré par le développeur
  4. Ajouter une limite de débit sur le point de terminaison de téléversement au niveau du proxy inverse ou du WAF pour atténuer le vecteur OOM lié aux requêtes concurrentes.
  5. Nettoyer périodiquement les répertoires temporaires orphelins avec une tâche cron externe, puisque la bibliothèque ne dispose d'aucun nettoyage interne.

Chronologie de divulgation

Contexte du paquet

  • Environ 28 000 téléchargements mensuels sur PyPI (27 756 au cours des 30 jours précédant le 2026-05-07, avec un volume quotidien soutenu malgré l'archivage du dépôt). Source : pypistats.org.
  • Dernière version publiée : 0.6.1 (ligne stable). Les préversions vont jusqu'à 0.7.0a2.
  • Dépendance requise : dash. Dépendance optionnelle : pyyaml. Licence : MIT.
  • 11 paquets dépendants, 6 dépôts dépendants.
  • 153 étoiles GitHub.
  • Dépôt archivé le 2025-07-19 (Issue #153).
  • Aucun CVE antérieur (vérification effectuée sur NVD, GitHub Advisory Database, Snyk et OSV le 2026-03-19).

Références

  • https://www.cve.org/CVERecord?id=CVE-2026-38361
  • https://nvd.nist.gov/vuln/detail/CVE-2026-38361
  • https://github.com/fohrloop/dash-uploader
  • https://github.com/fohrloop/dash-uploader/blob/stable/dash_uploader/httprequesthandler.py
  • https://github.com/fohrloop/dash-uploader/issues/153
  • https://pypi.org/project/dash-uploader/
  • https://pypistats.org/packages/dash-uploader
  • https://libraries.io/pypi/dash-uploader
  • https://pepy.tech/project/dash-uploader
  • https://cwe.mitre.org/data/definitions/400.html
  • https://cwe.mitre.org/data/definitions/670.html
  • https://docs.python.org/3/library/functions.html#all

Découvreur

Muhammad Fitri Bin Mohd Sultan

Télécharger l’outil
Identifiant CVECVE-2026-38361 (NVD)
VulnérabilitéConsommation incontrôlée de ressources (CWE-400), Implémentation toujours incorrecte du flux de contrôle (CWE-670)
CVSS 3.17.5 / Élevée (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Produitdash-uploader
Versions concernéesde 0.1.0 à 0.7.0a2 (les 18 versions)
Version corrigéeaucune (projet archivé le 2025-07-19)
Vecteur d'attaqueÀ distance, sans authentification
DécouvreurMuhammad Fitri Bin Mohd Sultan
Attribué parMITRE, 2026-05-07
LiéCVE-2026-38360 (traversée de chemin dans la même bibliothèque)
DateÉvénement
2026-03-19Vulnérabilités découvertes lors d'une recherche en sécurité sur un déploiement en production.
2026-03-22Demande de CVE soumise à MITRE.
2026-05-07CVE-2026-38361 attribué par MITRE.
2026-05-07Avis public publié.
2026-05-09Enregistrement CVE publié sur la base de données CVE de MITRE et le NVD.