Modellens utdata är opålitlig indata. Hitta var din kod glömmer det.
Statisk analys av koden runt din LLM — koden som bygger prompten, anropar modellen och gör något med svaret. Inte modellen. Inte promptens motståndskraft mot en jailbreak. Koden.
Gratisplanen omfattar 3 projekt och 30 analyser per månad, utan gräns för antalet användare och utan betalkort. Den här analysen ingår i den.
Problemet
En modell är inte ett bibliotek. Den är en opålitlig tolk: du ger den en sträng och den ger en tillbaka. Allt som påverkade den strängen — användarens egen prompt, en sida den fick se, ett dokument den fick, resultatet från ett annat verktyg — påverkade svaret.
Svaret är ofarligt tills koden ger det en förmåga. Faran är inte att en modell sa något; den är att ett program trodde på det. Varje ställe där ett program behandlar genererad text som kod, som ett kommando, som en fråga, som en sökväg eller som en URL är en injection med ett hopp till — och till skillnad från frågan om en prompt går att kringgå med en jailbreak är det hoppet synligt i källkoden.
Vad Cybseco letar efter
Där modellens utdata når något som agerar. Det är motorns egna kategorier, allvarlighetsgrader och CWE-identifierare.
eval, exec, compile, new Function, pickle.loads, yaml.load — svaret blir ett program.os.system, subprocess, child_process.exec, execSync — svaret blir ett kommando.execute, raw, createQuery — text-to-SQL är precis det här mönstret, och DROP TABLE är en rimlig fortsättning.open, readFile, shutil.rmtree, unlink — ../../etc/passwd är en lika rimlig fortsättning.requests, httpx, fetch, axios, urlopen — server-side request forgery, vald av modellen.Ett konkret exempel
Nio rader, och hela riskens form.
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(…) — ett anrop som returnerar modellens utdata. Analysatorn binder variabeln som värdet tilldelades, och det är just det som låter den följa värdet genom funktionen utan interprocedurell analys.answer innehåller text som en angripare påverkat. Mellan anropet och sänkan finns ingenting som inspekterar den, begränsar den eller avbildar den på en fast uppsättning operationer.exec(…) — texten blir ett program i applikationens egen process, med dess autentiseringsuppgifter, dess nätverk och dess filsystem.task — direkt, eller genom ett dokument som modellen fick se — väljer vad som körs. Det här är fjärrkörning av kod med ett hopp till.Kört mot den nuvarande motorn ger det utdraget ett fynd: llm-output-to-code-execution, CWE-94, allvarlighetsgrad kritisk, tillförlitlighet hög, på raden exec. Tillförlitligheten är hög eftersom variabeln är bunden till ett verkligt completion-anrop. Ett namn som bara ser ut som ett modellsvar — llm_response, reply — rapporteras i stället med medelhög tillförlitlighet, för det är en gissning och att påstå annat vore att ljuga om bevisningen.
Vad det här inte är
Andra LLM-specifika risker i koden
Var och en utlöstes på ett prov mot den nuvarande motorn innan den skrevs ned här.
api_key, ett lösenord, ett IBAN eller en patientjournal placerad i texten du skickar. Rapporteras där en verklig promptkontext byggs, inte på varje f-sträng som råkar innehålla en nyckel.PythonREPLTool, ShellTool, en kodtolk, en terminal. Att ge ett av dem gör varje fråga om prompt injection till en fråga om fjärrkörning av kod.allow_dangerous_deserialization=True, trust_remote_code=True, dangerouslyAllow… — ett ramverk stängde av det eftersom det var osäkert.BLOCK_NONE, safety_settings=None, moderation=false.hub.pull(…), en promptmall som laddas över HTTP. Den som kontrollerar den slutpunkten kontrollerar instruktionerna.sk-…, sk-ant-…, AIza…, hf_… incheckade i repositoryt.text-davinci-*, gpt-4-0314, claude-instant — svagare instruktionshierarki, ingen separation av systemprompten.Varför du skulle tro på något av det här
Leverantörsoberoende av konstruktion. Analysatorn känner igen formen — något producerar text, något förbrukar den — snarare än ett visst SDK:s skrivsätt. Den namnger det ramverk den såg när den kan (OpenAI, Anthropic, Google, Azure OpenAI, Mistral, Bedrock, Ollama, LiteLLM, LangChain, LangGraph, LlamaIndex, Semantic Kernel, AutoGen, CrewAI, Hugging Face) så att ett fynd kan säga varifrån det kom. Det är en etikett på fyndet, inte en integration per SDK, och ett ramverk som saknas i listan analyseras på exakt samma sätt.
Se Cybseco resonera om ett verkligt system
Se den interaktiva demon och begär sedan en guidad provperiod för ditt team.