À mesure que les grands modèles de langage (LLM) génèrent de plus en plus de code fonctionnel et sont intégrés aux pipelines de développement et aux piles d'agents, le risque que caché or malveillant Les instructions — qu'elles soient intégrées aux résultats du modèle, injectées via des pages Web ou des plugins tiers, ou introduites lors de l'entraînement du modèle — peuvent provoquer un comportement dangereux lors de l'exécution de ce code.
D'après des témoignages d'utilisateurs circulant dans les communautés de développeurs, un développeur de logiciels a subi une perte de données catastrophique — environ 800 Go de fichiers ont été supprimés, Y compris la l'application CursorAI entière elle-même — après avoir exécuté le code généré avec l'aide de Gemini 3 tout en travaillant à l'intérieur du IDE CursorAIÀ mesure que les développeurs s'appuient de plus en plus sur les LLM pour la génération de code, les conséquences des scripts non vérifiés ou non sécurisés deviennent plus graves.
Il est donc primordial de savoir comment détecter et supprimer les codes dangereux générés par LLM.
Qu’est-ce que le « code caché » dans le contexte de ChatGPT et des LLM ?
Que signifie l'expression « code caché » ?
Le terme « code caché » est un terme générique utilisé par les développeurs pour décrire toutes les instructions intégrées ou tout contenu exécutable dans le texte (ou les fichiers) qu'un LLM ingère ou émet, notamment :
- Instructions de type prompteur intégré dans le contenu utilisateur (par exemple, « Ignorer les instructions précédentes… » caché dans un PDF).
- Personnages invisibles ou des espaces de largeur nulle utilisés pour masquer des jetons ou enfreindre les hypothèses de tokenisation.
- Charges utiles codées (base64, encodage URL, intégrations stéganographiques dans des images ou des documents).
- HTML/JS caché ou des blocs de script inclus dans du contenu formaté qui pourraient être interprétés par des moteurs de rendu en aval.
- Métadonnées ou annotations (commentaires de fichiers, calques cachés dans les PDF) qui donnent des instructions aux systèmes de recherche ou au modèle.
- Comportements implicites résultant de code généré qui utilise des API dangereuses (par exemple,
eval,exec,subprocess, ou appels réseau/système) — même lorsque l'intention n'est pas explicitement malveillante. - Instructions injectées par prompt qui amènent le modèle à générer un code contenant des commandes cachées ou une logique de type porte dérobée, car un attaquant a manipulé l'invite ou le contexte.
Ces vecteurs d'attaque sont souvent appelés injection rapide or injection rapide indirecte Lorsque l'objectif est de modifier le comportement d'un modèle, la communauté de la sécurité considère désormais l'injection de prompts comme une vulnérabilité LLM fondamentale, et l'OWASP l'a formalisée en tant que catégorie de risque LLM.
En quoi est-ce différent des logiciels malveillants classiques ou des attaques XSS ?
La différence est la sémantique Couche : l’injection d’instructions cible le comportement d’exécution du modèle plutôt que le système d’exploitation hôte ou le moteur de rendu du navigateur. Cela dit, tout code HTML ou script caché exécuté par un moteur de rendu web constitue une attaque exécutable (de type XSS) ; les couches sémantique et d’exécution doivent être protégées. Les experts et les chercheurs du secteur qualifient l’injection d’instructions de « défi majeur en matière de sécurité » et continuent de publier des stratégies d’atténuation.
Pourquoi LLM peut-il produire du code caché ou dangereux ?
Comportement du modèle, données d'entraînement et contexte d'instruction
Les modèles linéaires logiques (LLM) sont entraînés à produire des suites plausibles en fonction du contexte et des instructions. Si le contexte contient des indices adverses, ou si un utilisateur demande au modèle de générer du code effectuant des actions complexes, le modèle peut produire du code incluant un comportement subtil ou explicite.
Les LLM produisent un code plausible mais non sécurisé
Les LLM sont optimisés pour la fluidité et l'utilité, et non pour la sécurité face aux effets secondaires destructeurs. Ils généreront volontiers un résumé succinct rm -rf /path/to/dir or shutil.rmtree() Les appels sont souvent suivis d'appels suite à des demandes de « nettoyage », et comme leurs réponses sont généralement formulées avec assurance, les utilisateurs peuvent copier-coller sans trop se renseigner. Ce phénomène d'« hallucination confiante » explique pourquoi des requêtes apparemment anodines deviennent dangereuses.
Automatisation des flux de travail d'obfuscation
Les acteurs malveillants automatisent désormais l'obfuscation du code en enchaînant les appels LLM : un modèle génère une charge utile, un autre la retravaille pour éviter la détection par signature, et ainsi de suite. Les rapports sur les menaces du secteur et les analyses des fournisseurs de 2025 documentent cette « obfuscation assistée par l'IA » comme une technique émergente.
Comment détecter du code caché dans les résultats d'un modèle ?
Liste de contrôle de triage rapide
- Rechercher les caractères Unicode invisibles/inhabituels (caractères de liaison de largeur nulle, espaces de largeur nulle, marques d'ordre des octets, homoglyphes non ASCII).
- Exécuter l'analyse statique / l'analyse syntaxique AST identifier l'utilisation d'API puissantes (
eval,exec,subprocess,os.system, appels réflexifs). - Recherchez les charges utiles encodées (base64, blobs hexadécimaux, chaînes longues répétées ou contenu compressé).
- Vérifier les motifs d'obfuscation (concaténation de chaînes de caractères qui construit les noms d'API, arithmétique des caractères,
chr()chaînes). - Utiliser l'analyse sémantique pour confirmer si le code effectue effectivement des opérations d'E/S, de mise en réseau ou de modification du système de fichiers.
Détection de motifs statiques (rapide, première ligne)
- Analyse syntaxique et vérification de la syntaxe prenant en compte le langage. Analysez immédiatement le résultat généré en blocs de code plutôt qu'en prose. Exécutez les outils de formatage et d'analyse statique de code (Black/Prettier, pylint, eslint). Les règles d'analyse statique doivent signaler l'utilisation de
eval,exec,rm -rf, des appels de sous-processus bruts, ou des tubes shell qui construisent des commandes dynamiquement. - Analyseurs de modèles de jetons et de chaînes de caractères. Rechercher les jetons et les modèles à haut risque :
sudo, des chemins absolus comme/home/,C:\,rm -rf,shutil.rmtree,subprocess.Popen, des blobs base64 en ligne, de longues chaînes non interprétables et des shebangs qui changent le contexte de l'interpréteur. - Numérisation secrète et contrôles de provenance. Détecter les identifiants codés en dur, les URL pointant vers des registres non fiables ou le code qui extrait dynamiquement des paquets à partir de sources arbitraires.
L'analyse statique permet de détecter rapidement de nombreux problèmes évidents et son exécution est peu coûteuse dans le cadre d'un processus d'intégration continue.
Détection sémantique et contextuelle (approfondie)
- Analyse des intentions. Utilisez un modèle secondaire ou un moteur de règles pour classifier l'intention du code généré : s'agit-il de « lecture », « écriture », « suppression », « réseau », « installation » ? Toute action catégorisée comme suppression/écriture doit déclencher une escalade.
- Analyse des flux de données. Analysez le code pour détecter si des chemins non validés ou fournis par l'utilisateur peuvent accéder à des API potentiellement dangereuses. Par exemple, si une variable issue d'une sortie LLM ou d'un fichier distant est ensuite concaténée à une commande shell, signalez-le.
- Corrélation de provenance. Conservez une trace complète de la conversation, des messages système et des pages de contexte. Si des résultats suspects correspondent à un document externe ou à un appel de plugin particulier, cela peut indiquer une injection de messages système ou un contexte corrompu.
Détection dynamique et comportementale (la plus fiable)
- Exécution en environnement isolé avec surveillance. Exécutez le code généré dans un environnement éphémère strictement contrôlé, sans réseau, sans montage de périphériques hôtes et avec filtrage des appels système (seccomp). Surveillez l'activité du système de fichiers, les tentatives d'appels réseau, la création de processus et les E/S inhabituelles.
- Tests de canari. Avant d'exécuter le code sur des données réelles, testez-le sur des répertoires synthétiques contenant des fichiers sentinelles ; surveillez les suppressions ou les écrasements.
- Heuristiques comportementales. Recherchez les boucles qui parcourent les répertoires parents, les opérations récursives sans vérification de profondeur ou les modèles de renommage susceptibles d'endommager de nombreux fichiers (par exemple, écrire à plusieurs reprises le même nom de fichier).
L'analyse dynamique est le seul moyen de détecter les charges utiles obscurcies, retardées ou déclenchées uniquement lors de l'exécution.
Comment supprimer ou neutraliser le code caché avant d'exécuter les résultats LLM ?
Suppression défensive vs. modification sémantique
La « suppression de code caché » poursuit deux objectifs :
- Désinfection — Supprimer tout contenu manifestement non codant ou suspect (Unicode invisible, caractères de largeur nulle, données Base64 ajoutées). Cela ne doit pas altérer la logique initiale, qui est bienveillante.
- Neutralisation — Pour toute opération exécutant ou appelant des services externes, désactivez ces appels ou rendez-les inopérants jusqu'à vérification.
Toujours préférer neutralisation + révision Concernant la suppression aveugle : supprimer arbitrairement des portions de code peut engendrer des comportements anormaux ou inattendus. Il est préférable de remplacer les constructions suspectes par des stubs explicites et journalisés qui gèrent les erreurs de manière sécurisée (en levant des exceptions ou en renvoyant des valeurs par défaut sûres).
Étape 1 — Traiter le code généré comme des données non fiables
N’exécutez jamais de code directement depuis ChatGPT (ou tout autre LLM) sans l’avoir préalablement soumis à un processus de suppression et de sécurisation. Ce processus doit être mis en œuvre par une politique de sécurité et automatisé dans le cadre d’une intégration continue et d’un déploiement continu (CI/CD).
Étape 2 — Extraire et normaliser le code
- Normaliser le texte et supprimer les caractères de largeur nulleSupprimez les caractères tels que U+200B, U+200C, U+200D, U+FEFF et autres points de code de formatage/de largeur nulle. Consignez les éléments supprimés à des fins d'audit. Cette étape élimine de nombreux encodages « cachés » utilisés pour la dissimulation visuelle.
- Supprimer tout le contexte non lié au codeSupprimer le texte narratif, les commentaires cachés et les conteneurs HTML/Markdown. Convertir le code au format canonique à l'aide de formateurs de langage (Black, Prettier) afin de normaliser les espaces et les caractères de contrôle masqués.
- Rejeter ou mettre en quarantaine le code contenant ces constructions: dynamique
eval, appels de sous-processus bruts (os.system,subprocess.Popen), des blobs base64 en ligne décodés pour l'exécution, ou intégrés#!directives qui tentent de modifier le contexte de l'interprète. Normaliser le texte et supprimer les caractères de largeur nulle
Supprimez les caractères tels que U+200B, U+200C, U+200D, U+FEFF et autres points de code de formatage/de largeur nulle. Consignez les éléments supprimés à des fins d'audit. Cette étape élimine de nombreux encodages « cachés » utilisés pour la dissimulation visuelle.
Étape 3 — Analyser en AST et remplacer les nœuds à risque
Une fois le code analysé et converti en AST, trouvez les nœuds qui appellent l'exécution dynamique (par exemple, exec), ou qui génèrent des noms de fonctions par programmation. Remplacez-les par des stubs sécurisés qui lèvent une exception contrôlée indiquant « comportement dynamique non sécurisé bloqué ». Générez une copie anonymisée du code source basé sur l'AST pour analyse. Exécutez des contrôles de sécurité (règles semgrep personnalisées pour votre environnement). Lorsqu'une correspondance est trouvée, marquez-la et neutralisez-la.
Étape 4 — Durcissement statique et réécriture
- Réécriture automatisée: faire passer le code par un outil de nettoyage automatisé qui remplace les appels dangereux par des wrappers sécurisés — par exemple, remplacer
os.system()/subprocessavec un exécuteur sandbox approuvé qui applique des délais d'expiration et des blocages réseau. - Contrôle des capacitésModifier ou supprimer les clés API, les jetons ou les appels aux points de terminaison privilégiés ; les remplacer par des adaptateurs factices pour les tests locaux. Empêcher l’inclusion accidentelle de secrets ou d’URL.
- Réécritures de dépendances: bloc dynamique
pip/npmInstallations créées par le code. Nécessite que les dépendances soient déclarées et approuvées via votre registre.
Étape 5 — Courir dans un bac à sable agressif
- Conteneurs éphémères / microVMsExécutez le code dans un conteneur/une machine virtuelle sans accès réseau, sans accès aux identifiants de l'hôte et avec un accès limité au système de fichiers. Des technologies comme gVisor, Firecracker ou des services d'exécution éphémère dédiés conviennent. Si le code doit accéder aux E/S, utilisez un proxy qui applique une politique de sécurité.
- Filtres d'appels système et seccompLimiter les appels système autorisés. Les écritures de fichiers en dehors d'un répertoire temporaire doivent être bloquées.
- limites de ressources/de temps: définir des limites de processeur/mémoire/temps afin que même les bombes logiques ne puissent pas s'exécuter indéfiniment.
L'exécution en environnement isolé (sandbox) associée à une surveillance permet souvent de détecter des charges utiles que les contrôles statiques ne détectent pas. Les recommandations du secteur et les livres blancs récents préconisent le sandboxing comme mesure d'atténuation essentielle.
Quels outils et règles automatisés devraient figurer dans votre pipeline ?
Composants de chaîne d'outils recommandés
- Module d'assainissement Unicode (Bibliothèques personnalisées ou existantes). Doit consigner les caractères normalisés.
- Analyseur syntaxique + analyseur AST pour chaque langage cible (Python)
ast,typed-ast, analyseurs JavaScript, analyseurs Java). - Analyseurs statiques / SAST: Bandit (Python), Semgrep (multilingue, personnalisable), ESLint avec plugins de sécurité.
- Entropie et heuristiques de décodage: détecter base64/hex/gzip et acheminer vers l'inspection.
- Exécution du bac à sable: conteneur minimal avec profil seccomp/AppArmor strict ou interpréteur au niveau du langage avec appels système désactivés.
- agent chargé de l'application des politiques: un composant qui détermine les modules autorisés, les points de terminaison autorisés et les wrappers d'API sécurisés.
- La piste de vérification: journaux immuables qui enregistrent la sortie originale, la sortie nettoyée, les différences et les décisions.
Exemples de modèles semgrep (conceptuels)
Utilisez des règles courtes et prudentes qui signalent l'utilisation de fonctions dangereuses. Par exemple :
- chaise
eval,exec,Functionconstructeur (JS), importations dynamiques ou noms d'API construits sous forme de chaînes de caractères. - Signaler les appels réseau en dehors de la liste d'autorisation (par exemple,
requests.getà des hôtes inconnus). - L'indicateur écrit sur des chemins sensibles (
/etc, dossiers système) ou la création de processus.
(Conservez ces éléments comme paramètres de configuration propres à chaque organisation et affinez-les au fil du temps.)
Quels sont des exemples pratiques de désinfection (exemples sûrs) ?
Vous trouverez ci-dessous des exemples défensifs non dangereux que vous pouvez adapter. assainissement et détection Des extraits de code — et non des instructions d'exploitation.
Exemple : supprimer les caractères de largeur nulle (Python, défensif)
import re
ZERO_WIDTH_RE = re.compile(r'')
def strip_zero_width(s: str) -> str:
cleaned = ZERO_WIDTH_RE.sub('', s)
return cleaned
Cela supprime les caractères souvent utilisés par les attaquants pour dissimuler du code dans un texte autrement visible. Il est impératif de consigner systématiquement les éléments supprimés et de les intégrer à la piste d'audit.
Exemple : analyser et inspecter l’AST (Python, conceptuel)
import ast
def has_dynamic_exec(source: str) -> bool:
tree = ast.parse(source)
for node in ast.walk(tree):
if isinstance(node, ast.Call):
if getattr(node.func, 'id', '') in ('eval', 'exec',):
return True
if isinstance(node, ast.Attribute):
if getattr(node, 'attr', '') in ('popen', 'system'):
return True
return False
If has_dynamic_exec Renvoie True, ne pas exécuter le code ; remplacer plutôt le nœud dynamique par un stub sûr et exiger une vérification.
Remarque : ces exemples sont de nature défensive. Ne supprimez pas la journalisation, l’audit ou la vérification humaine de votre processus.
En conclusion : traitez toujours les résultats de LLM comme du code non fiable.
Les gestionnaires de versions sont de puissants outils de productivité : ils permettent de produire du code élégant, d’accélérer la rédaction des brouillons et d’automatiser les tâches répétitives. Mais au moment de l’exécution, les règles de sécurité changent : **Les résultats du modèle doivent être traités comme des artefacts non fiables.**La combinaison d'injections rapides, de recherches sur les portes dérobées et de divulgations de vulnérabilités dans le monde réel au cours des 18 à 30 derniers mois met en évidence un point clair : la surface à risque s'est étendue et continuera d'évoluer.
Des défenses pratiques combinant l'analyse syntaxique, l'analyse statique, les tests dynamiques en environnement isolé, la gouvernance et les exercices d'intrusion continus permettent de stopper la plupart des attaques. Cependant, les équipes doivent également investir dans des contrôles organisationnels : le principe du moindre privilège, la traçabilité et une culture qui exige la vérification des résultats des analyses de vulnérabilité. Le secteur développe des outils et des cadres de référence pour faciliter ces pratiques ; en attendant, l'adoption de la liste de contrôle ci-dessus réduit le risque qu'une charge utile cachée passe inaperçue.
Les développeurs peuvent accéder à la dernière API LLM, telle que : Claude Sonnet 4.5 API et Aperçu de Gemini 3 Pro etc. via CometAPI, la dernière version du modèle est constamment mis à jour avec le site officiel. Pour commencer, explorez les capacités du modèle dans la section cour de récréation et consultez le Guide de l'API Pour des instructions détaillées, veuillez vous connecter à CometAPI et obtenir la clé API avant d'y accéder. API Comet proposer un prix bien inférieur au prix officiel pour vous aider à vous intégrer.
Prêt à partir ?→ Inscrivez-vous à CometAPI dès aujourd'hui !
Si vous souhaitez connaître plus de conseils, de guides et d'actualités sur l'IA, suivez-nous sur VK, X et Discord!


