CWE-94 : injection de code, quand la donnée devient du programme
- Accueil
- Référentiels & catalogues
- Cwe
- CWE-94 : injection de code, quand la donnée devient du programme
CWE-94 : injection de code, quand la donnée devient du programme
Section intitulée « CWE-94 : injection de code, quand la donnée devient du programme »Dixième du CWE Top 25 2025. Le libellé officiel est Improper Control of Generation of Code (‘Code Injection’) : « contrôle incorrect de la génération de code ». Le nom officiel insiste sur la génération, et il a raison : la faiblesse n’est pas de recevoir du code, c’est d’en fabriquer avec des morceaux venus de l’extérieur.
Un notaire rédige un acte en recopiant les indications que lui dicte le client. Si le client dicte « et par la présente, le notaire me cède son étude », le notaire consciencieux note la phrase comme une déclaration du client. Le notaire distrait l’intègre comme une clause de l’acte, qu’il signe ensuite. CWE-94 décrit ce notaire.
→ Lire l’explication complète de la marmotte
Ce que la classe recouvre exactement
Section intitulée « Ce que la classe recouvre exactement »Le produit construit tout ou partie d’un segment de code à partir d’une entrée influencée depuis l’extérieur, sans neutraliser les éléments spéciaux qui peuvent modifier la syntaxe ou le comportement du code prévu.
Le point à retenir est la frontière avec la classe voisine. Dans l’injection de commande système, l’attaquant écrit pour un interpréteur extérieur au programme : celui du système d’exploitation. Ici, il écrit dans le langage du programme lui-même, qui évalue son propre code à l’exécution. La conséquence est la même (exécuter ce qu’on veut), mais le chemin diffère, et la correction aussi : on ne durcit pas un appel de commande, on supprime une évaluation dynamique.
La classe couvre aussi bien le code évalué immédiatement que le code écrit pour plus tard : une entrée insérée dans un fichier de configuration qui sera chargé au prochain démarrage, ou dans une bibliothèque générée, relève de la même faiblesse, avec un délai. Ce décalage temporel rend ces cas difficiles à relier à leur cause, car l’exécution se produit longtemps après l’injection, parfois dans un autre processus.
Sa place dans l’arbre
Section intitulée « Sa place dans l’arbre »CWE-94 est une base avec deux parents, et c’est révélateur. Dans la famille des injections, son parent est CWE-74, le tronc commun : une donnée franchit une frontière de langage sans être requalifiée. Dans la famille du code dynamique, son parent est la classe CWE-913, « contrôle incorrect des ressources de code gérées dynamiquement », qui couvre tout ce qui consiste à lire ou écrire des variables, des objets, des classes ou des fonctions désignés à l’exécution.
Trois entrées descendent d’elle, et chacune correspond à une situation que l’on rencontre vraiment :
CWE-95, l’injection dans une évaluation dynamique, c’est-à-dire la fonctionevalet ses équivalents dans tous les langages interprétés, le cas d’école ;CWE-96, l’injection dans du code enregistré : l’entrée est écrite dans un fichier qui sera exécuté ensuite ;CWE-1336, l’injection dans un moteur de modèles, la plus actuelle. Un moteur de modèles est un petit langage : quand une donnée extérieure est placée non pas dans les variables fournies au modèle mais dans le texte du modèle lui-même, l’attaquant obtient l’exécution de ce petit langage, qui donne souvent accès à l’ensemble du langage hôte.
Une cousine mérite d’être citée, car elle appartient à la même famille et occupe le site : CWE-502, la désérialisation de données non fiables, au rang 15. Elle n’injecte pas de texte de code, elle injecte un état qui déclenche l’exécution de code déjà présent. Même résultat, mécanisme franchement différent.
Pourquoi elle est si haut
Section intitulée « Pourquoi elle est si haut »Parce que l’évaluation dynamique est un raccourci partout disponible. Toutes les plateformes qui permettent à leurs utilisateurs d’écrire des formules, des règles, des filtres ou des extensions finissent par évaluer du texte fourni. Les outils d’automatisation, les systèmes de modèles de documents, les plateformes à faible code et les règles métier configurables sont les familles de produits les plus représentées.
Parce que les moteurs de modèles sont devenus universels. Générateurs de pages, systèmes de notification par courriel, outils de rapport : dès qu’un utilisateur peut personnaliser un modèle, la frontière entre « donnée affichée » et « modèle exécuté » devient une décision d’architecture que personne n’a prise explicitement.
Parce que la gravité est maximale. Comme pour l’injection de commande, le résultat est l’exécution de code ; le score du classement en tient compte.
Le mécanisme, et où le site le traite
Section intitulée « Le mécanisme, et où le site le traite »Le site traite les deux voisinages immédiats. Pour la chaîne qui mène d’une donnée à l’exécution sans passer par du texte de code, la désérialisation non sécurisée et ses chaînes de gadgets est la référence ; pour la variante dans un format de configuration apparemment inoffensif, l’attaque par désérialisation YAML montre qu’un fichier de paramètres peut instancier des objets.
Deux renvois plus actuels. La pollution de prototype en JavaScript illustre le parent CWE-913 : on ne fournit pas de code, on modifie les ressources de code gérées dynamiquement, et le comportement du programme change. Et côté intelligence artificielle, valider le function calling d’un LLM traite le cas où le « code » généré est un appel de fonction produit par un modèle : la sortie d’un générateur statistique ne doit pas plus être évaluée sans contrôle qu’une saisie d’utilisateur.
Ce qu’une équipe en fait
Section intitulée « Ce qu’une équipe en fait »Supprimer l’évaluation dynamique. Dans la quasi-totalité des cas, elle sert à contourner une absence de conception : une table de correspondance, un ensemble de fonctions nommées, un interpréteur restreint écrit pour l’occasion remplacent un eval et se testent. La règle pratique : toute évaluation dynamique encore présente dans un dépôt doit être justifiée par écrit, nominativement.
Séparer strictement le modèle des données quand un moteur de modèles est en jeu. Les données passent par les variables, jamais par le texte du modèle. Si les utilisateurs doivent pouvoir écrire des modèles, le moteur doit tourner en mode restreint, sans accès aux objets du langage hôte : et ce mode doit être vérifié, car beaucoup de moteurs annoncent une restriction qui tombe au premier attribut spécial.
Isoler l’exécution lorsqu’un langage utilisateur est une fonctionnalité assumée : processus séparé, droits réduits, limites de temps et de mémoire. On ne protège plus le code, on contient ce qu’il peut faire.
- CWE-94: Improper Control of Generation of Code, MITRE, liste 4.20 : définition, parents CWE-74 et CWE-913, filles CWE-95, CWE-96 et CWE-1336.
- 2025 CWE Top 25, MITRE : rang 10.
🐝 Ce qui arrive si on s’en passe
Section intitulée « 🐝 Ce qui arrive si on s’en passe »Une équipe qui ne nomme pas cette classe laisse subsister les évaluations dynamiques héritées, chacune justifiée par une petite commodité : une formule paramétrable dans un écran d’administration, un filtre personnalisable dans un export, un modèle de courriel que le service commercial peut modifier. Aucune de ces fonctions ne ressemble à du code, et c’est précisément le problème : personne ne les relit comme telles. Le jour où l’une d’elles est atteinte par une saisie non filtrée, l’attaquant n’obtient pas des données mais l’exécution, dans le processus de l’application, avec ses accès à la base et à ses secrets. Le coût de l’enquête est aggravé par le décalage temporel propre à cette classe : quand l’injection a été écrite dans un fichier de configuration ou un modèle enregistré, l’exécution se produit au redémarrage suivant, et plus rien dans les journaux ne relie l’effet à sa cause.
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Un programme est un texte d’instructions, écrit à l’avance et exécuté ensuite. Mais certains langages de programmation permettent aussi de fabriquer des instructions pendant l’exécution, puis de les exécuter aussitôt. C’est pratique : on peut ainsi laisser l’utilisateur écrire une formule de calcul, une règle de tri, un modèle de courrier.
Le danger apparaît quand le programme fabrique ces instructions en y recopiant ce que l’utilisateur a saisi. L’utilisateur peut alors écrire non plus une donnée, mais des instructions de son choix, que le programme exécutera comme si leur auteur en était le développeur. Il ne s’agit plus de lire des informations auxquelles on n’a pas droit : il s’agit de faire faire au programme ce qu’on veut.
C’est le défaut que le catalogue CWE appelle CWE-94, « injection de code ». Il est proche d’un autre, CWE-78, mais il faut les distinguer : dans CWE-78, l’attaquant fait exécuter une commande par le système d’exploitation ; ici, il fait exécuter des instructions par l’application elle-même, dans son propre langage.
La variante la plus fréquente aujourd’hui concerne les modèles de documents. Un modèle est un texte à trous, dans lequel le programme vient remplacer les trous par des valeurs. Si l’utilisateur peut modifier non pas les valeurs mais le texte à trous, il écrit dans le petit langage du modèle, qui donne souvent accès à tout le reste.
La bonne pratique consiste à ne jamais fabriquer d’instructions à partir d’une saisie. Quand une application doit vraiment offrir cette souplesse, elle doit faire tourner ce code dans un espace confiné, aux droits réduits et au temps limité : non pour empêcher l’abus, qui devient inévitable, mais pour qu’il ne sorte pas de la pièce.
À lire aussi
- CWE-77 : injection de commande, la classe au-dessus de l'interpréteur systèmeCWE-77, improper neutralization of special elements used in a command : ce que la classe recouvre au-delà de CWE-78, ses filles dont l'injection de prompt CWE-1427, et son rang 23 au Top 25 2025.
- CWE-89 : injection SQL, la classe de la requête concaténéeCWE-89, neutralisation incorrecte d'éléments spéciaux dans une commande SQL : ce que la classe recouvre, sa place dans l'arbre CWE, ce qui la distingue de CWE-943 et CWE-20, et pourquoi elle reste au deuxième rang du Top 25 2025.
- CWE-79 : cross-site scripting, la classe au premier rang du Top 25CWE-79, neutralisation incorrecte des entrées lors de la génération d'une page web : ce que la classe recouvre, sa place dans l'arbre CWE, ses sept variantes, et pourquoi elle arrive première du Top 25 2025.
- CWE-434 : téléversement d'un fichier de type dangereuxCWE-434, unrestricted upload of file with dangerous type : ce que la classe recouvre, le rôle décisif du traitement automatique, ses pairs CWE-351, CWE-430 et CWE-436, et son rang 12 au Top 25 2025.
Pages voisines
La citent
- CWE-434 : téléversement d'un fichier de type dangereux
- CWE-77 : injection de commande, la classe au-dessus de l'interpréteur système
- CICD-SEC-3 : abus de la chaîne de dépendances
CWE-94 : injection de code, quand la donnée devient du programme
Elle cite
- Lien dans les deux sens :CWE-502 : désérialisation de données non fiables
- Lien dans les deux sens :CWE-78 : injection de commande système, quand le programme appelle un interpréteur
- Lien dans les deux sens :CWE Top 25 2025 : les vingt-cinq faiblesses logicielles les plus dangereuses
- Attaque par désérialisation YAML non sécurisée
- Comment valider le function calling d’un LLM
- Démonstration de pollution de prototype JavaScript
- Désérialisation non sécurisée et chaîne de gadgets
: les deux pages se citent l’une l’autre.
