Kostenloses Konto erstellen
Codesicherheit von LLM-Anwendungen

Die Ausgabe Ihres Modells ist nicht vertrauenswürdige Eingabe. Finden Sie, wo Ihr Code das vergisst.

Statische Analyse des Codes rund um Ihr LLM — des Codes, der den Prompt baut, das Modell aufruft und mit der Antwort etwas anfängt. Nicht das Modell. Nicht die Widerstandsfähigkeit des Prompts gegen einen Jailbreak. Der Code.

Der kostenlose Tarif umfasst 3 Projekte und 30 Analysen pro Monat, ohne Begrenzung der Nutzerzahl und ohne Kreditkarte. Diese Analyse läuft darin.

Das Problem

Ein Modell ist keine Bibliothek. Es ist ein nicht vertrauenswürdiger Interpreter: Sie geben ihm eine Zeichenkette, und es gibt Ihnen eine zurück. Was immer diese Zeichenkette beeinflusst hat — der Prompt des Nutzers, eine Seite, die ihm gezeigt wurde, ein Dokument, das ihm gegeben wurde, das Ergebnis eines anderen Werkzeugs — hat die Antwort beeinflusst.

Die Antwort ist harmlos, solange der Code ihr keine Fähigkeit gibt. Die Gefahr liegt nicht darin, dass ein Modell etwas gesagt hat, sondern darin, dass ein Programm es geglaubt hat. Jede Stelle, an der ein Programm erzeugten Text als Code, als Befehl, als Abfrage, als Pfad oder als URL behandelt, ist eine Injection mit einem zusätzlichen Sprung — und anders als die Frage, ob ein Prompt per Jailbreak umgangen werden kann, ist dieser Sprung im Quelltext sichtbar.

Wonach Cybseco sucht

Dort, wo Modellausgabe etwas erreicht, das handelt. Dies sind die Kategorien, Schweregrade und CWE-Kennungen der Engine selbst.

Codeausführung — CWE-94
kritisch
eval, exec, compile, new Function, pickle.loads, yaml.load — die Antwort wird zum Programm.
Eine Shell — CWE-78
kritisch
os.system, subprocess, child_process.exec, execSync — die Antwort wird zum Befehl.
Eine SQL-Abfrage — CWE-89
hoch
execute, raw, createQuery — Text-to-SQL ist genau dieses Muster, und DROP TABLE ist eine plausible Vervollständigung.
Ein Dateipfad — CWE-22
hoch
open, readFile, shutil.rmtree, unlink — ../../etc/passwd ist ebenfalls eine plausible Vervollständigung.
Eine ausgehende Anfrage — CWE-918
hoch
requests, httpx, fetch, axios, urlopen — Server-Side Request Forgery, vom Modell gewählt.

Ein konkretes Beispiel

Neun Zeilen, und die ganze Gestalt des Risikos.

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)
Quelle
client.chat.completions.create(…) — ein Aufruf, der Modellausgabe zurückgibt. Der Analyzer bindet die Variable, der sie zugewiesen wurde; genau das erlaubt ihm, dem Wert ohne interprozedurale Analyse durch die Funktion zu folgen.
Fluss
answer enthält von einem Angreifer beeinflussten Text. Zwischen Aufruf und Senke prüft ihn nichts, schränkt ihn nichts ein und bildet ihn nichts auf eine feste Menge von Operationen ab.
Senke
exec(…) — der Text wird zum Programm im Prozess der Anwendung selbst, mit deren Zugangsdaten, deren Netzwerk und deren Dateisystem.
Warum das zählt
Alles, was task beeinflussen kann — direkt oder über ein Dokument, das dem Modell gezeigt wurde — wählt aus, was ausgeführt wird. Das ist Remote Code Execution mit einem zusätzlichen Sprung.

Gegen die aktuelle Engine ausgeführt, erzeugt dieser Ausschnitt einen Befund: llm-output-to-code-execution, CWE-94, Schweregrad kritisch, Konfidenz hoch, in der Zeile exec. Die Konfidenz ist hoch, weil die Variable an einen tatsächlichen Completion-Aufruf gebunden ist. Ein Name, der nur wie eine Modellantwort aussieht — llm_response, reply — wird stattdessen mit mittlerer Konfidenz gemeldet, denn das ist eine Vermutung, und etwas anderes zu behaupten wäre eine Lüge über die Beweislage.

Was dies nicht ist

Kein Test des Modells
Wir sondieren das Modell nicht, unterziehen es keinem Red Teaming und bewerten nicht, wie es sich unter Druck verhält. Nichts hier sagt, ob ein Prompt per Jailbreak umgangen werden kann: Das ist aus dem Quelltext nicht entscheidbar, und es zu behaupten wäre genau die Art von Aussage, zu deren Vermeidung diese Engine existiert.
Keine vollständige Erkennung von Prompt Injection
Indirekte Injection wird dort gemeldet, wo nicht vertrauenswürdiger Inhalt nachweislich einen Prompt erreicht. Einen Kanal, den wir im Code nicht sehen, melden wir nicht.
Keine Garantie über einen Agenten
Wir melden, dass einem Agenten ein Werkzeug gegeben wurde, das Code oder Befehle ausführt. Was der Agent damit zur Laufzeit tut, liegt jenseits dessen, was statische Analyse entscheiden kann.
Ergänzend zur KI-Sicherheit zur Laufzeit
Guardrails, Evaluations-Harnesses und Red Teaming beantworten Fragen, die dies nicht beantworten kann, und dies beantwortet Fragen, die jene nicht beantworten können. Keines ersetzt das andere.

Weitere LLM-spezifische Risiken im Code

Jedes wurde an einem Beispiel gegen die aktuelle Engine ausgelöst, bevor es hier aufgeschrieben wurde.

Geheimnisse und personenbezogene Daten in einen Prompt interpoliert — CWE-200
Ein api_key, ein Passwort, eine IBAN oder ein Patientendatensatz im Text, den Sie senden. Gemeldet dort, wo tatsächlich ein Prompt-Kontext aufgebaut wird, nicht bei jedem f-String, der zufällig einen Schlüssel enthält.
Ein Agent, dem ein Werkzeug für Code oder Befehle gegeben wurde — CWE-250
PythonREPLTool, ShellTool, ein Code-Interpreter, ein Terminal. Eines davon zu gewähren macht aus jeder Prompt-Injection-Frage eine Frage nach Remote Code Execution.
Ein Schutzmechanismus des Frameworks wieder abgeschaltet — CWE-502
allow_dangerous_deserialization=True, trust_remote_code=True, dangerouslyAllow… — ein Framework hatte das deaktiviert, weil es unsicher war.
Sicherheitskontrollen des Anbieters deaktiviert — CWE-693
BLOCK_NONE, safety_settings=None, moderation=false.
Ein Prompt oder eine Agentendefinition, die zur Laufzeit geladen wird — CWE-829
hub.pull(…), eine über HTTP geladene Prompt-Vorlage. Wer diesen Endpunkt kontrolliert, kontrolliert die Anweisungen.
Nicht vertrauenswürdiger Inhalt direkt in einen Prompt geladen — CWE-77
Eine gescrapte Seite, ein PDF, ein Repository, ein Wiki. Das ist der Kanal für indirekte Injection, erkannt daran, woher der Text stammt, und nicht daran, was er sagt.
Ein Modell-API-Schlüssel im Quelltext — CWE-798
sk-…, sk-ant-…, AIza…, hf_… im Repository eingecheckt.
Ein zurückgezogenes oder abgelöstes Modell fest im Code — CWE-1104
text-davinci-*, gpt-4-0314, claude-instant — schwächere Anweisungshierarchie, keine Trennung des System-Prompts.

Warum Sie das alles glauben sollten

Ein veröffentlichter Benchmark
Precision, Recall und F1 je CWE, je Sprache und je Analyseebene, über einen versionierten, von Hand annotierten Korpus. Die Zahlen ansehen.
Ein veröffentlichter Geltungsbereich
Jede Ebene, die wir nicht messen, wird benannt, mit Begründung. Die Methodik lesen.
Validierung an öffentlichem Code
Analysierte Repositories und Commits, angetroffene Sprachen, Abschlussquote und Determinismus — Mengen und Quoten, keine Genauigkeitsaussagen. Die Läufe ansehen.
Jeder Befund trägt seinen Beleg
Die Datei, die Zeile, das erkannte Konstrukt und die CWE. Ein Befund, den Sie nicht prüfen können, ist ein Befund, nach dem Sie nicht handeln sollten.

Anbieterunabhängig von Grund auf. Der Analyzer erkennt die Form — etwas erzeugt Text, etwas verbraucht ihn — und nicht die Schreibweise eines bestimmten SDK. Er benennt das Framework, das er gesehen hat, wenn er es kann (OpenAI, Anthropic, Google, Azure OpenAI, Mistral, Bedrock, Ollama, LiteLLM, LangChain, LangGraph, LlamaIndex, Semantic Kernel, AutoGen, CrewAI, Hugging Face), damit ein Befund sagen kann, woher er stammt. Das ist eine Kennzeichnung am Befund, keine Integration je SDK, und ein Framework, das in dieser Liste fehlt, wird genau gleich analysiert.

Sehen Sie Cybseco über ein reales System nachdenken

Sehen Sie sich die interaktive Demo an und fordern Sie dann einen begleiteten Test für Ihr Team an.