La sortie de votre modèle est une entrée non fiable. Trouvez où votre code l'oublie.
Analyse statique du code autour de votre LLM — le code qui construit le prompt, appelle le modèle et fait quelque chose de la réponse. Pas le modèle. Pas la résistance du prompt à un jailbreak. Le code.
L'offre gratuite couvre 3 projets et 30 analyses par mois, sans limite sur le nombre d'utilisateurs et sans carte bancaire. Cette analyse y est incluse.
Le problème
Un modèle n'est pas une bibliothèque. C'est un interpréteur non fiable : vous lui passez une chaîne, il vous en rend une. Tout ce qui a influencé cette chaîne — le prompt de l'utilisateur, une page qu'on lui a montrée, un document qu'on lui a donné, le résultat d'un autre outil — a influencé la réponse.
La réponse est inoffensive tant que le code ne lui donne pas de pouvoir. Le danger n'est pas qu'un modèle ait dit quelque chose ; c'est qu'un programme l'ait cru. Chaque endroit où un programme traite du texte généré comme du code, une commande, une requête, un chemin ou une URL est une injection avec un saut de plus — et contrairement à la question de savoir si un prompt peut être contourné, ce saut est visible dans les sources.
Ce que Cybseco recherche
Là où la sortie du modèle atteint quelque chose qui agit. Ce sont les catégories, les sévérités et les identifiants CWE propres au moteur.
eval, exec, compile, new Function, pickle.loads, yaml.load — la réponse devient un programme.os.system, subprocess, child_process.exec, execSync — la réponse devient une commande.execute, raw, createQuery — le text-to-SQL suit exactement ce schéma, et DROP TABLE est une complétion plausible.open, readFile, shutil.rmtree, unlink — ../../etc/passwd est une complétion tout aussi plausible.requests, httpx, fetch, axios, urlopen — une falsification de requête côté serveur, choisie par le modèle.Un exemple concret
Neuf lignes, et toute la forme du risque.
from openai import OpenAI
client = OpenAI()
def run_plan(task: str):
answer = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": task}],
)
exec(answer.choices[0].message.content)client.chat.completions.create(…) — un appel qui renvoie la sortie du modèle. L'analyseur lie la variable à laquelle elle a été affectée, ce qui lui permet de suivre la valeur dans la fonction sans analyse interprocédurale.answer contient du texte influencé par un attaquant. Rien, entre l'appel et le point d'arrivée, ne l'inspecte, ne le contraint ni ne le ramène à un ensemble fixe d'opérations.exec(…) — le texte devient un programme dans le processus même de l'application, avec ses identifiants, son réseau et son système de fichiers.task — directement, ou via un document montré au modèle — choisit ce qui s'exécute. C'est une exécution de code à distance avec un saut de plus.Exécuté sur le moteur actuel, cet extrait produit un résultat : llm-output-to-code-execution, CWE-94, sévérité critique, confiance élevée, sur la ligne exec. La confiance est élevée parce que la variable est liée à un véritable appel de complétion. Un nom qui ressemble seulement à une réponse de modèle — llm_response, reply — est rapporté avec une confiance moyenne, parce que c'est une supposition et que prétendre le contraire serait mentir sur la preuve.
Ce que ce n'est pas
Autres risques propres aux LLM dans le code
Chacun a été déclenché sur un échantillon, contre le moteur actuel, avant d'être écrit ici.
api_key, un mot de passe, un IBAN ou un dossier médical placé dans le texte que vous envoyez. Rapporté là où un véritable contexte de prompt est construit, pas sur n'importe quelle f-string qui contiendrait une clé.PythonREPLTool, ShellTool, un interpréteur de code, un terminal. Accorder l'un d'eux transforme toute question d'injection de prompt en question d'exécution de code à distance.allow_dangerous_deserialization=True, trust_remote_code=True, dangerouslyAllow… — un framework l'avait désactivé parce que c'était dangereux.BLOCK_NONE, safety_settings=None, moderation=false.hub.pull(…), un gabarit de prompt chargé en HTTP. Qui contrôle ce point d'accès contrôle les instructions.sk-…, sk-ant-…, AIza…, hf_… versionnés dans le dépôt.text-davinci-*, gpt-4-0314, claude-instant — hiérarchie d'instructions plus faible, pas de séparation du prompt système.Pourquoi croire tout cela
Indépendant du fournisseur par construction. L'analyseur reconnaît la forme — quelque chose produit du texte, quelque chose le consomme — plutôt que l'écriture propre à un SDK. Il nomme le framework qu'il a vu quand il le peut (OpenAI, Anthropic, Google, Azure OpenAI, Mistral, Bedrock, Ollama, LiteLLM, LangChain, LangGraph, LlamaIndex, Semantic Kernel, AutoGen, CrewAI, Hugging Face) pour qu'un résultat puisse dire d'où il vient. C'est une étiquette sur le résultat, pas une intégration par SDK, et un framework absent de cette liste est analysé exactement de la même manière.
Voyez Cybseco raisonner sur un système réel
Regardez la démo interactive, puis demandez un essai guidé pour votre équipe.