ISMS Copilot Docs

SSE-Redaktion: Schutz von LLM-Systemprompts in Streaming-Architekturen

Von Better ISMS — Februar 2026

Von Better ISMS — Februar 2026

Wenn Sie ein Produkt auf Basis eines LLM entwickeln, ist Ihr Systemprompt Ihre Produktlogik. Wenn jemand ihn extrahiert, erhält er Ihre Logik, Ihre Schutzmechanismen, Ihren Wettbewerbsvorteil — alles. Und wenn Sie Antworten per Server-Sent Events streamen (was Sie wahrscheinlich tun), ist der Schutz vor Extraktion schwieriger, als Sie denken.

Dieser Beitrag beschreibt die SSE-Redaktion, eine Technik, die wir für ISMS Copilot entwickelt haben, um Systemprompt-Leaks während des Streams zu erkennen und zu neutralisieren. Wir teilen die Architektur, damit andere, die LLM-Produkte entwickeln, etwas Ähnliches implementieren können.

Das Problem

Die meisten LLM-Anwendungen streamen Antworten chunkweise an den Client, wobei jeder Chunk sofort nach seiner Generierung gesendet wird. Es gibt keinen Schritt „Gesamte Antwort vor dem Senden überprüfen“ — das würde den Zweck des Streamings zunichtemachen.

Dies schafft eine Sicherheitslücke: Wenn ein Jailbreak-Prompt das Modell dazu bringt, seine Systemanweisungen preiszugeben, ist der Inhalt bereits auf dem Weg zum Client, bevor Sie ihn stoppen können. Bis Sie merken, was passiert ist, hat der Nutzer bereits Hunderte oder Tausende Zeichen Ihres Systemprompts gesehen.

Traditionelle Ausgabefilterung funktioniert hier nicht. Sie können nicht die gesamte Antwort puffern (Latenz tötet die UX), und Sie können nicht jeden winzigen Chunk isoliert überprüfen (ein 5-Wort-Fragment sieht nicht wie ein Systemprompt aus).

Für allgemeine Strategien zur Verhinderung von Jailbreaks siehe Jailbreaks und Prompt-Injections abmildern. SSE-Redaktion ist eine Defense-in-Depth-Maßnahme für den Fall, dass diese Präventionen versagen.

Die Architektur

Die SSE-Redaktion funktioniert in vier Stufen.

Stufe 1 — Fingerprinting. Bevor eine Konversation stattfindet, extrahieren Sie eine Reihe von Fingerprint-Phrasen aus Ihrem Systemprompt. Dabei handelt es sich um charakteristische Zeichenfolgen, die nur gemeinsam auftreten, wenn das Modell seine Anweisungen reproduziert. Sie sollten Phrasen aus verschiedenen Abschnitten Ihres Prompts wählen — Rollendefinitionen, Namensbeschränkungen, Verhaltensregeln. Die Anzahl der Fingerprints und die Matching-Schwelle sind anpassbare Parameter, die Sie geheim halten.

Stufe 2 — Akkumulation und periodische Überprüfung. Während das Modell Chunks streamt, sammelt eine Schutzkomponente den gesamten Antworttext. In regelmäßigen Abständen (gemessen an der Zeichenanzahl, nicht pro Chunk) überprüft sie den akkumulierten Inhalt gegen die Fingerprint-Sammlung. Eine Überprüfung jedes Chunks wäre ineffizient — die Fingerprints benötigen ausreichend Kontext, um sinnvoll zu matchen.

Stufe 3 — Fehlerweiterleitung. Wenn die Schutzkomponente genug Fingerprint-Treffer erkennt, wirft sie einen typisierten Fehler (in unserem Fall SystemPromptLeakError). Hier liegt die Feinheit. In einer Streaming-Architektur verfügt die Chunk-Verarbeitungsschleife typischerweise über ein try/catch für die Handhabung fehlerhafter SSE-Daten (schlechtes JSON, unerwartete Formate). Dieser generische Catch-Block würde Ihren Sicherheitsfehler verschlucken, wenn Sie nicht aufpassen. Sie benötigen eine Schutzklausel, die Ihren spezifischen Fehlertyp erneut wirft, bevor der generische Handler ausgeführt wird:

catch (e) {
  if (e instanceof Error && e.name === 'SystemPromptLeakError') throw e;
  // generische Fehlerbehandlung läuft für alles andere weiter
}

Das ist eine Einzeiler, aber ohne ihn ist das gesamte Erkennungssystem wirkungslos. Die Schutzkomponente erkennt Leaks perfekt in den Logs, während der Stream fröhlich weiter Ihren Systemprompt an den Angreifer liefert. Das haben wir auf die harte Tour gelernt — unsere Schutzkomponente erkannte Leaks perfekt in den Logs, während sie absolut nichts tat, um sie zu stoppen.

Stufe 4 — Redaktion. Sobald der Fehler bis zum Stream-Controller propagiert, sendet dieser ein Redaktions-SSE-Ereignis an den Client. Der Client ersetzt alles, was bereits gerendert wurde, durch eine Ablehnungsnachricht. Gleichzeitig ersetzt der Server den gespeicherten Inhalt in der Datenbank, sodass das Leak nicht bestehen bleibt.

Was der Nutzer sieht

Der Angreifer sieht kurzzeitig teilweise gestreamte Inhalte — vielleicht ein paar Sekunden lang — dann wird die gesamte Antwort durch eine generische Ablehnungsnachricht ersetzt. Die Erfahrung ist: Text erscheint, verschwindet dann und wird ersetzt. Die teilweise gesehenen Inhalte sind unvollständig und mit normalem Antworttext vermischt, was sie für die Extraktion unzuverlässig macht.

Erfahren Sie mehr darüber, wie Ablehnungsnachrichten funktionieren, in Ablehnungen und Geltungsbereichsgrenzen behandeln.

Das Catch-Block-Problem

Dies verdient besondere Betonung, weil es sich um eine Art von Fehler handelt, der alle Tests besteht, aber in der Produktion versagt.

Wenn Sie asynchrone Generatoren für das Streaming verwenden, sieht Ihre SSE-Parsing-Schleife wahrscheinlich so aus:

for (const line of sseLines) {
  try {
    const data = JSON.parse(line);
    const text = extractText(data);
    await onChunkCallback(text);  // <-- Schutzkomponente läuft hier
    yield text;
  } catch (e) {
    console.error('Fehler beim Parsen des Chunks:', e);
    // fährt mit der nächsten Zeile fort
  }
}

Der Callback befindet sich innerhalb des try-Blocks. Wenn die Schutzkomponente einen Fehler wirft, protokolliert der catch ihn als Parse-Fehler und fährt fort. In unserem Fall erkannte die Schutzkomponente das Leak korrekt bei jedem einzelnen Chunk nach dem Schwellenwert — die Logs zeigten, dass SystemPromptLeakError wiederholt ausgelöst wurde — während der Stream normal abgeschlossen wurde, den vollständigen geleakten Prompt in der Datenbank speicherte und an den Client sendete.

Die zusätzliche Komplikation: Dieses Verhalten ist laufzeitabhängig. In Node.js können Fehler von asynchronen Generator-Callbacks anders propagieren als in Deno. Unsere Tests bestanden in der Node.js-Testumgebung, weil der Fehler zufällig propagiert wurde. In der Deno-Produktion wurde er verschluckt. Wenn Sie dies implementieren, testen Sie in Ihrer tatsächlichen Produktionslaufzeitumgebung, nicht nur in Ihrem Test-Runner.

Designentscheidungen, die erwähnenswert sind

Warum Fingerprints statt Embedding-Ähnlichkeit oder exaktem Matching? Fingerprints sind schnell (String-Matching), deterministisch (keine Modellaufrufe) und robust gegen Umschreibungen. Das Modell paraphrasiert seinen eigenen Systemprompt während eines Leaks selten — es reproduziert ihn wortwörtlich oder fast wortwörtlich. Embedding-Ähnlichkeit fügt Latenz pro Überprüfung hinzu und birgt das Risiko von False Positives bei legitimen Compliance-Inhalten. Exaktes Substring-Matching ist zu spröde (Whitespace, Formatierungsunterschiede).

Warum periodisch statt bei jedem Chunk überprüfen? Chunks sind klein (oft 3–10 Zeichen). Ein einzelner Chunk ist für die Erkennung bedeutungslos. Die Akkumulation bis zu einem Mindestschwellenwert vor der Überprüfung reduziert die Berechnung und stellt sicher, dass genug Kontext für ein zuverlässiges Matching vorhanden ist.

Warum nicht die gesamte Antwort puffern? Pufferung tötet die Streaming-UX. Nutzer erwarten, dass Text in Echtzeit erscheint. Ein 2-Sekunden-Puffer ist spürbar; das Puffern einer vollständigen Antwort mit 4000+ Zeichen ist inakzeptabel. SSE-Redaktion bewahrt das Echtzeit-Streaming für 99,99 % der Konversationen und greift nur bei einem aktiven Leak ein.

Warum auch in der Datenbank ersetzen? Wenn Sie nur auf dem Client redigieren, bleibt der geleakte Inhalt serverseitig bestehen. Jeder mit Datenbankzugriff, jede Exportfunktion, jeder Konversationsverlauf-Endpunkt würde ihn preisgeben.

Was dies nicht löst

SSE-Redaktion ist eine Defense-in-Depth-Maßnahme, keine Wunderwaffe.

Sie verhindert nicht, dass das Modell versucht, zu leaken. Das übernehmen die Anweisungen in Ihrem Systemprompt selbst (explizite Ablehnungsanweisungen, Beschränkungsabschnitte). SSE-Redaktion ist das Sicherheitsnetz für den Fall, dass diese Anweisungen versagen — und mit genug Kreativität gelingen Jailbreaks gelegentlich.

Sie verhindert keine Leaks, die kürzer als der Erkennungsschwellenwert sind. Wenn jemand das Modell dazu bringt, einen einzelnen Satz des Systemprompts preiszugeben, erreicht die Fingerprint-Anzahl nicht den Schwellenwert. Dies ist beabsichtigt — Sie wägen zwischen dem Erkennen vollständiger Extraktionen (hohe Sicherheit) und dem Markieren teilweiser Erwähnungen (hohes False-Positive-Risiko) ab.

Der Angreifer sieht vor der Redaktion teilweise Inhalte. Für ein paar Sekunden ist gestreamter Text sichtbar. Dies ist inhärent für Streaming-Architekturen. Die teilweisen Inhalte sind unvollständig und strukturlos, aber es handelt sich nicht um null Exposition.

SSE-Redaktion ergänzt, ersetzt aber nicht die Best Practices für Systemprompt-Sicherheit. Siehe Systemprompts und Arbeitsbereich und benutzerdefinierte Anweisungen schützen für grundlegende Sicherheitsmaßnahmen.

Implementierungscheckliste

Wenn Sie dies für Ihr eigenes LLM-Produkt umsetzen möchten:

  1. Extrahieren Sie Fingerprint-Phrasen aus Ihrem Systemprompt — wählen Sie charakteristische, abschnittsübergreifende Zeichenfolgen.
  2. Erstellen Sie eine Schutzkomponente, die gestreamte Inhalte akkumuliert und periodisch gegen Fingerprints überprüft.
  3. Definieren Sie eine typisierte Fehlerklasse mit einem eindeutigen Namen für die Leakerkennung.
  4. Überprüfen Sie jeden Catch-Block in Ihrer Streaming-Pipeline — fügen Sie Schutzklauseln zum erneuten Werfen Ihres Fehlertyps hinzu.
  5. Behandeln Sie in Ihrem Stream-Controller den Fehler, indem Sie ein Redaktionsereignis senden und den gespeicherten Inhalt ersetzen.
  6. Behandeln Sie auf dem Client das Redaktionsereignis, indem Sie den gerenderten Inhalt durch eine Ablehnungsnachricht ersetzen.
  7. Testen Sie in Ihrer Produktionslaufzeitumgebung, nicht nur in Ihrem Test-Runner.
  8. Halten Sie Ihre Fingerprints, Schwellenwerte und Überprüfungsintervalle geheim.

Abschließender Gedanke

Der schwierigste Teil daran war nicht der Erkennungsalgorithmus — es war ein Einzeiler-Fehler in einem Catch-Block, der das gesamte System lautlos deaktivierte. Sicherheit in Streaming-Architekturen scheitert auf der Ebene der Infrastruktur, nicht auf der Algorithmus-Ebene. Wenn Sie LLM-Sicherheitsfunktionen entwickeln, verfolgen Sie den vollständigen Fehlerpfad von der Erkennung bis zur benutzerseitigen Aktion und überprüfen Sie ihn in Ihrer tatsächlichen Produktionsumgebung.

Für einen umfassenderen Überblick über KI-Sicherheitspraktiken bei ISMS Copilot siehe Übersicht zu KI-Sicherheit & verantwortungsvoller Nutzung.

Better ISMS entwickelt Compliance-Tools für Informationssicherheitsteams. ISMS Copilot ist unser KI-Assistent für ISO 27001, SOC 2, DSGVO und verwandte Frameworks.

On this page