Skapa gratiskonto
Kodsäkerhet i LLM-applikationer

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.

Kodexekvering — CWE-94
kritisk
eval, exec, compile, new Function, pickle.loads, yaml.load — svaret blir ett program.
Ett skal — CWE-78
kritisk
os.system, subprocess, child_process.exec, execSync — svaret blir ett kommando.
En SQL-fråga — CWE-89
hög
execute, raw, createQuery — text-to-SQL är precis det här mönstret, och DROP TABLE är en rimlig fortsättning.
En filsökväg — CWE-22
hög
open, readFile, shutil.rmtree, unlink — ../../etc/passwd är en lika rimlig fortsättning.
En utgående begäran — CWE-918
hög
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)
Källa
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.
Flöde
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.
Sänka
exec(…) — texten blir ett program i applikationens egen process, med dess autentiseringsuppgifter, dess nätverk och dess filsystem.
Varför det spelar roll
Allt som kan påverka 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

Inte ett test av modellen
Vi sonderar inte modellen, utsätter den inte för red teaming och utvärderar inte hur den beter sig under press. Ingenting här säger om en prompt går att kringgå med en jailbreak: det går inte att avgöra från källkoden, och att hävda det vore precis den sortens påstående som den här motorn finns till för att undvika.
Inte fullständig upptäckt av prompt injection
Indirekt injection rapporteras där opålitligt innehåll bevisligen når en prompt. En kanal vi inte kan se i koden är en kanal vi inte rapporterar.
Ingen garanti om en agent
Vi rapporterar att en agent har fått ett verktyg som kör kod eller kommandon. Vad agenten sedan gör vid körning ligger utanför vad statisk analys kan avgöra.
Ett komplement till AI-säkerhet vid körning
Guardrails, utvärderingsriggar och red teaming besvarar frågor som det här inte kan besvara, och det här besvarar frågor som de inte kan. Ingendera ersätter den andra.

Andra LLM-specifika risker i koden

Var och en utlöstes på ett prov mot den nuvarande motorn innan den skrevs ned här.

Hemligheter och personuppgifter interpolerade i en prompt — CWE-200
En 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.
En agent som fått ett verktyg som kör kod eller kommandon — CWE-250
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.
Ett skydd i ramverket avstängt igen — CWE-502
allow_dangerous_deserialization=True, trust_remote_code=True, dangerouslyAllow… — ett ramverk stängde av det eftersom det var osäkert.
Leverantörens säkerhetskontroller avstängda — CWE-693
BLOCK_NONE, safety_settings=None, moderation=false.
En prompt eller agentdefinition som hämtas vid körning — CWE-829
hub.pull(…), en promptmall som laddas över HTTP. Den som kontrollerar den slutpunkten kontrollerar instruktionerna.
Opålitligt innehåll laddat rakt in i en prompt — CWE-77
En skrapad sida, en PDF, ett repository, en wiki. Det här är kanalen för indirekt injection, igenkänd på var texten kom ifrån snarare än på vad den säger.
En API-nyckel för en modell skriven i källkoden — CWE-798
sk-…, sk-ant-…, AIza…, hf_… incheckade i repositoryt.
En tillbakadragen eller ersatt modell fastlåst i koden — CWE-1104
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

En publicerad benchmark
Precision, täckning och F1 per CWE, per språk och per analyslager, över ett versionerat, handmärkt korpus. Se siffrorna.
Ett publicerat omfång
Varje lager vi inte mäter är namngivet, med skälet. Läs metodiken.
Validering på publik kod
Analyserade repositories och commits, påträffade språk, slutförandegrad och determinism — volymer och andelar, inte påståenden om träffsäkerhet. Se körningarna.
Varje fynd bär sitt bevis
Filen, raden, konstruktionen som matchade och CWE:n. Ett fynd du inte kan kontrollera är ett fynd du inte bör agera på.

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.