bifroest/app/security/signals.py
2026-10-27 08:34:17 +01:00

36 lines
2.2 KiB
Python

"""Muster für Inhalte, die wie Anweisungen an eine KI aussehen.
Die Liste ist bewusst klein und präzise: Ein Treffer blockiert nichts, er wird
protokolliert (Ereignis untrusted_signal, Metrik aiw_untrusted_signals_total) und
der Inhalt für das Modell gekennzeichnet. Neue Muster hier ergänzen und in
tests/injection_corpus.py ein Beispiel dazu aufnehmen.
"""
import re
W = r"\W+(?:\w+\W+){0,%d}" # bis zu n Wörter dazwischen
PATTERNS: tuple[tuple[str, re.Pattern[str]], ...] = tuple((name, re.compile(rx, re.IGNORECASE)) for name, rx in (
("ignore_instructions", r"\b(ignore|disregard|forget|override)" + W % 2 + r"(all|any|previous|prior|above|"
r"earlier|your|the)" + W % 2 + r"(instructions?|rules|prompts?|guidelines)\b"),
("ignoriere_anweisungen", r"\b(ignorier\w*|vergiss|vergesst|missachte\w*)" + W % 3 + r"(alle|vorherige\w*|"
r"bisherige\w*|obige\w*|deine|sämtliche)" + W % 2 + r"(anweisung\w*|regeln|"
r"vorgaben|instruktion\w*)"),
("rollenwechsel", r"\b(you are now|from now on,? you (are|will|must)|du bist (jetzt|ab sofort|nun) (ein|eine|"
r"der|die|kein)|ab (jetzt|sofort) bist du)\b"),
("systemnachricht", r"\b(new|updated|neuer?|geänderter?)\s+system\s?-?prompt\b|\[\s*system\s*\]|"
r"<\|?(system|im_start)\|?>|\bsystem override\b"),
("einfassung", r"</?\s*(fremdinhalt|projektregeln|arbeitsnotiz|plan_schritte)\b"),
("tool_aufruf", r"\b(call|invoke|run|use|execute|rufe|nutze|verwende|führe)" + W % 3 +
r"(commit_change|merge_target|update_plan)\b"),
("rechte_umgehen", r"\b(bypass\w*|umgeh\w*|skip)" + W % 2 + r"(approvals?|freigabe\w*|reviews?|policy|"
r"policies|richtlinie\w*)\b"),
("geheimnisse", r"\b(send|reveal|leak|exfiltrate|post|schick\w*|verrat\w*|sende\w*|übermittle\w*)" + W % 4 +
r"(api[ _-]?keys?|secrets?|passw(or)?[dt]s?|zugangsdaten|credentials)\b"),
))
def scan(text: str) -> list[str]:
"""Namen der Muster, die im Text vorkommen (höchstens die ersten 200 000 Zeichen)."""
sample = text[:200_000]
return [name for name, pattern in PATTERNS if pattern.search(sample)]