Crea un account gratuito
Sicurezza del codice delle applicazioni LLM

L'output del tuo modello è input non attendibile. Trova dove il tuo codice se ne dimentica.

Analisi statica del codice attorno al tuo LLM — il codice che costruisce il prompt, chiama il modello e fa qualcosa della risposta. Non il modello. Non la resistenza del prompt a un jailbreak. Il codice.

Il piano gratuito copre 3 progetti e 30 analisi al mese, senza limiti al numero di utenti e senza carta di credito. Questa analisi vi rientra.

Il problema

Un modello non è una libreria. È un interprete non attendibile: gli passi una stringa e te ne restituisce una. Tutto ciò che ha influenzato quella stringa — il prompt dell'utente, una pagina che gli è stata mostrata, un documento che gli è stato dato, il risultato di un altro strumento — ha influenzato la risposta.

La risposta è innocua finché il codice non le dà una capacità. Il pericolo non è che un modello abbia detto qualcosa; è che un programma ci abbia creduto. Ogni punto in cui un programma tratta il testo generato come codice, come un comando, come una query, come un percorso o come una URL è una injection con un salto in più — e, a differenza della domanda se un prompt possa essere aggirato con un jailbreak, quel salto è visibile nel sorgente.

Che cosa cerca Cybseco

Dove l'output del modello raggiunge qualcosa che agisce. Queste sono le categorie, le severità e gli identificatori CWE propri del motore.

Esecuzione di codice — CWE-94
critica
eval, exec, compile, new Function, pickle.loads, yaml.load — la risposta diventa un programma.
Una shell — CWE-78
critica
os.system, subprocess, child_process.exec, execSync — la risposta diventa un comando.
Una query SQL — CWE-89
alta
execute, raw, createQuery — il text-to-SQL è esattamente questo schema, e DROP TABLE è un completamento plausibile.
Un percorso del filesystem — CWE-22
alta
open, readFile, shutil.rmtree, unlink — anche ../../etc/passwd è un completamento plausibile.
Una richiesta in uscita — CWE-918
alta
requests, httpx, fetch, axios, urlopen — server-side request forgery, scelta dal modello.

Un esempio concreto

Nove righe, e tutta la forma del rischio.

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)
Sorgente
client.chat.completions.create(…) — una chiamata che restituisce output del modello. L'analizzatore lega la variabile a cui è stato assegnato, ed è questo che gli permette di seguire il valore attraverso la funzione senza analisi interprocedurale.
Flusso
answer contiene testo influenzato da un attaccante. Tra la chiamata e il punto di arrivo nulla lo ispeziona, lo vincola o lo riconduce a un insieme fisso di operazioni.
Punto di arrivo
exec(…) — il testo diventa un programma nel processo stesso dell'applicazione, con le sue credenziali, la sua rete e il suo filesystem.
Perché conta
Qualunque cosa possa influenzare task — direttamente o tramite un documento mostrato al modello — sceglie che cosa viene eseguito. Questa è esecuzione di codice da remoto con un salto in più.

Eseguito sul motore attuale, quel frammento produce un risultato: llm-output-to-code-execution, CWE-94, severità critica, confidenza alta, sulla riga exec. La confidenza è alta perché la variabile è legata a una vera chiamata di completamento. Un nome che somiglia soltanto a una risposta del modello — llm_response, reply — viene invece segnalato con confidenza media, perché quella è una supposizione e sostenere il contrario sarebbe mentire sulle prove.

Che cosa non è

Non è un test del modello
Non sondiamo il modello, non facciamo red teaming e non valutiamo come si comporta sotto pressione. Nulla qui dice se un prompt possa essere aggirato con un jailbreak: non è decidibile dal sorgente, e affermarlo sarebbe esattamente il tipo di dichiarazione che questo motore esiste per evitare.
Non è un rilevamento completo della prompt injection
L'injection indiretta viene segnalata dove contenuto non attendibile raggiunge dimostrabilmente un prompt. Un canale che non vediamo nel codice è un canale che non segnaliamo.
Non è una garanzia su un agente
Segnaliamo che a un agente è stato concesso uno strumento che esegue codice o comandi. Ciò che l'agente poi fa a runtime è fuori da quanto l'analisi statica può decidere.
Complementare alla sicurezza dell'IA a runtime
Guardrail, banchi di valutazione e red teaming rispondono a domande a cui questo non può rispondere, e questo risponde a domande a cui loro non possono. Nessuno dei due sostituisce l'altro.

Altri rischi specifici degli LLM nel codice

Ciascuno è stato attivato su un campione contro il motore attuale prima di essere scritto qui.

Segreti e dati personali interpolati in un prompt — CWE-200
Una api_key, una password, un IBAN o una cartella clinica inseriti nel testo che invii. Segnalato dove viene costruito un vero contesto di prompt, non su ogni f-string che per caso contenga una chiave.
Un agente a cui è stato dato uno strumento che esegue codice o comandi — CWE-250
PythonREPLTool, ShellTool, un interprete di codice, un terminale. Concederne uno trasforma ogni domanda sulla prompt injection in una domanda sull'esecuzione di codice da remoto.
Una protezione del framework rimessa su disattivato — CWE-502
allow_dangerous_deserialization=True, trust_remote_code=True, dangerouslyAllow… — un framework l'aveva disattivata perché non era sicura.
Controlli di sicurezza del provider disattivati — CWE-693
BLOCK_NONE, safety_settings=None, moderation=false.
Un prompt o una definizione di agente recuperati a runtime — CWE-829
hub.pull(…), un template di prompt caricato via HTTP. Chi controlla quell'endpoint controlla le istruzioni.
Contenuto non attendibile caricato direttamente in un prompt — CWE-77
Una pagina estratta dal web, un PDF, un repository, un wiki. Questo è il canale dell'injection indiretta, riconosciuto da dove proviene il testo e non da ciò che dice.
Una chiave API di modello scritta nel sorgente — CWE-798
sk-…, sk-ant-…, AIza…, hf_… committati nel repository.
Un modello ritirato o superato fissato nel codice — CWE-1104
text-davinci-*, gpt-4-0314, claude-instant — gerarchia delle istruzioni più debole, nessuna separazione del prompt di sistema.

Perché crederci

Un benchmark pubblicato
Precisione, richiamo e F1 per CWE, per linguaggio e per livello di analisi, su un corpus versionato ed etichettato a mano. Vedi i numeri.
Un perimetro pubblicato
Ogni livello che non misuriamo è nominato, con la ragione. Leggi la metodologia.
Validazione su codice pubblico
Repository e commit analizzati, linguaggi incontrati, tasso di completamento e determinismo — volumi e tassi, non affermazioni di accuratezza. Vedi le esecuzioni.
Ogni risultato porta la sua prova
Il file, la riga, il costrutto individuato e il CWE. Un risultato che non puoi verificare è un risultato su cui non dovresti agire.

Indipendente dal provider per costruzione. L'analizzatore riconosce la forma — qualcosa produce testo, qualcosa lo consuma — anziché la scrittura di un singolo SDK. Nomina il framework che ha visto quando può (OpenAI, Anthropic, Google, Azure OpenAI, Mistral, Bedrock, Ollama, LiteLLM, LangChain, LangGraph, LlamaIndex, Semantic Kernel, AutoGen, CrewAI, Hugging Face) perché un risultato possa dire da dove viene. Quella è un'etichetta sul risultato, non un'integrazione per SDK, e un framework assente da quell'elenco viene analizzato esattamente allo stesso modo.

Guarda Cybseco ragionare su un sistema reale

Guarda la demo interattiva, poi richiedi una prova guidata per il tuo team.