
Zweischichtige LLM-Firewall, die Prompt-Injection-Eingaben durch Regex-Regeln plus einen Gemini-Klassifikator blockiert und Leaks von Geheimnissen oder System-Prompts in Bot-Antworten abfängt.
Live-Demo: https://prompt-injection-firewall.streamlit.app 2-Minuten-Demo-Video: https://drive.google.com/file/d/1tzb75nFysisrCYa11Lqj6egDs5VNmc2n/view?usp=drivesdk
Eine zweistufige Firewall für einen LLM-Support-Bot: Sie prüft, was Nutzer eingeben, und was der Bot ausgibt.
Nutzer können versuchen, die Regeln eines Bots außer Kraft zu setzen („ignore previous instructions"), seine Persona zu wechseln oder ihn dazu zu bringen, seinen System-Prompt oder Geheimnisse preiszugeben. Dieses Projekt blockiert solche Eingaben, erkennt Leaks in den Antworten des Bots und misst, wie gut es funktioniert – einschließlich der Stellen, an denen es versagt.
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
Verwendetes Modell: gemini-3.1-flash-lite. Der kostenlose Tarif kann bei Auslastung 503 zurückgeben; der Code wartet und versucht es erneut.
Führe src\build_cases.py nicht aus, es sei denn, du möchtest data\cases.jsonl neu erstellen (es überschreibt die Datei; derselbe Seed ergibt dieselben Fälle).
deepset/prompt-injections (Apache-2.0): 12 Angriffe, 13 harmlos. Aufteilung: 15 dev, 10 hidden.data/train.parquet ist im Repo enthalten (Quelle: deepset/prompt-injections, Apache-2.0).| Set | Ebene | Ergebnis |
|---|---|---|
| dev | nur Regeln | Erkennung 2/9, Fehlalarm 0/6 |
| dev | Regeln + Gemini (final) | Erkennung 8/9, Fehlalarm 0/6 |
| dev | Ausgabe-Prüfung (final) | Leak erkannt 4/4, Fehlalarm 0/4 |
| hidden | Regeln + Gemini | Erkennung 3/3, Fehlalarm 0/7 |
| hidden | Ausgabe-Prüfung | Leak erkannt 3/3, Fehlalarm 0/1 |
Firewall vs. keine Firewall:
| Ohne | Mit | |
|---|---|---|
| dev: Angriffe, die den Bot erreichen | 9/9 | 1/9 |
| dev: harmlose fälschlich blockiert | 0/6 | 0/6 |
| hidden: Angriffe, die den Bot erreichen | 3/3 | 0/3 |
| hidden: harmlose fälschlich blockiert | 0/7 | 0/7 |
Das hidden-Set enthält nur 3 Angriffe, daher ist es ein schwaches Signal. Dev und hidden werden getrennt berichtet, weil ich den Klassifikator-Prompt auf dev abgestimmt habe.
Die vollständige Historie mit Zahlen steht in CHANGELOG.md. Kurz gesagt: