
Firewall LLM a due livelli che blocca gli input di prompt injection tramite regole regex più un classificatore Gemini, e intercetta le fughe di segreti o di system prompt nelle risposte del bot.
Demo live: https://prompt-injection-firewall.streamlit.app Video demo di 2 minuti: https://drive.google.com/file/d/1tzb75nFysisrCYa11Lqj6egDs5VNmc2n/view?usp=drivesdk
Un firewall a due livelli per un bot di supporto basato su LLM: controlla ciò che gli utenti inviano in ingresso e ciò che il bot invia in uscita.
Gli utenti possono tentare di sovrascrivere le regole di un bot ("ignora le istruzioni precedenti"), cambiarne la persona o indurlo a rivelare il proprio system prompt o segreti. Questo progetto blocca tali input, intercetta le fughe di informazioni nelle risposte del bot e misura quanto bene funziona, inclusi i casi in cui fallisce.
user input
|
v
[1] Rule layer (regex, fast, free) --match--> BLOCK
|no match
v
[2] LLM classifier (Gemini, JSON output, Pydantic validation, retries, fail-closed) --attack--> BLOCK
|benign
v
AcmeBot (Gemini + system prompt)
|
v
[3] Output check (canary token, secret patterns, system-prompt fragments) --leak--> BLOCK
|clean
v
answer to user
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
copy .env.example .env # then put your Gemini key in .env
python src\run_eval.py dev
python src\eval_output.py dev
python src\compare.py dev
streamlit run app.py # local demo
Modello usato: gemini-3.1-flash-lite. Il livello gratuito può restituire 503 quando è occupato; il codice attende e riprova.
Non eseguire src\build_cases.py a meno che tu non voglia ricostruire data\cases.jsonl (lo sovrascrive; lo stesso seed produce gli stessi casi).
deepset/prompt-injections (Apache-2.0): 12 attacchi, 13 benigni. Suddivisione: 15 dev, 10 hidden.data/train.parquet è incluso nel repository (fonte: deepset/prompt-injections, Apache-2.0).| Set | Livello | Risultato |
|---|---|---|
| dev | solo regole | rilevamento 2/9, falsi positivi 0/6 |
| dev | regole + Gemini (finale) | rilevamento 8/9, falsi positivi 0/6 |
| dev | controllo output (finale) | leak intercettati 4/4, falsi positivi 0/4 |
| hidden | regole + Gemini | rilevamento 3/3, falsi positivi 0/7 |
| hidden | controllo output | leak intercettati 3/3, falsi positivi 0/1 |
Firewall vs senza firewall:
| Senza | Con | |
|---|---|---|
| dev: attacchi che raggiungono il bot | 9/9 | 1/9 |
| dev: benigni bloccati erroneamente | 0/6 | 0/6 |
| hidden: attacchi che raggiungono il bot | 3/3 | 0/3 |
| hidden: benigni bloccati erroneamente | 0/7 | 0/7 |
Il set hidden contiene solo 3 attacchi, quindi è un segnale debole. Dev e hidden sono riportati separatamente perché ho ottimizzato il prompt del classificatore su dev.
La cronologia completa con i numeri è in CHANGELOG.md. In breve: