Wir haben kürzlich eine unserer vierteljährlichen Elastic OnWeek-Veranstaltungen abgeschlossen, die eine einzigartige Woche bietet, um Möglichkeiten außerhalb unseres regulären Alltags zu erkunden. In Übereinstimmung mit den jüngsten Veröffentlichungen von OWASP und der NSA AISC haben wir uns entschieden, einige Zeit mit den OWASP Top Ten Schwachstellen für LLMs nativ in Elastic zu verbringen. In diesem Artikel gehen wir auf einige Möglichkeiten ein, bösartige LLM-Aktivitäten mit ES|QL, nämlich:
- LLM01: Prompte Injektion
- LLM02: Unsichere Ausgabebehandlung
- LLM04: Modell-Denial-of-Service
- LLM06: Offenlegung sensibler Informationen
Elastic bietet die Möglichkeit, LLM-Anwendungen auf bösartiges Verhalten zu überwachen. Wir zeigen Ihnen einen Ansatz mit nur vier Schritten:
- Abfangen und Analysieren der LLM-Anfragen und -Antworten
- Anreicherung von Daten mit LLM-spezifischen Analyseergebnissen
- Senden von Daten an Elastic Security
- Das Schreiben von ES|QL-Erkennungsregeln, die später zur Reaktion verwendet werden können
Dieser Ansatz spiegelt unsere kontinuierlichen Bemühungen wider, fortschrittliche Erkennungsstrategien zu erforschen und zu implementieren, einschließlich der Entwicklung von Erkennungsregeln, die speziell auf LLMs zugeschnitten sind, und gleichzeitig mit neuen generativen KI-Technologien und Sicherheitsherausforderungen Schritt zu halten. Aufbauend auf dieser Grundlage haben wir im vergangenen Jahr unser Toolkit und unsere Fähigkeit zur Fortsetzung dieses proaktiven Weges im vergangenen Jahr erheblich verbessert.
Elastic hat den AI Assistant for Security veröffentlicht , in dem vorgestellt wird, wie der offene generative KI-Sidekick von der Search AI Platform unterstützt wird – einer Sammlung relevanter Tools für die Entwicklung fortschrittlicher Suchanwendungen. Unterstützt durch maschinelles Lernen (ML) und künstliche Intelligenz (KI) bietet dieser KI-Assistent leistungsstarke vorgefertigte Workflows wie Alarmzusammenfassung, Workflow-Vorschläge, Abfragekonvertierungen und Ratschläge zur Agentenintegration. Ich empfehle Ihnen dringend, mehr über den KI-Assistenten von Elastic zu lesen, um zu erfahren, wie sich die Funktionen nahtlos über Observability und Security erstrecken.
Wir können die Funktionen des KI-Assistenten als LLM-Anwendung eines Drittanbieters nutzen, um Anfragen und Antworten zu erfassen, zu prüfen und zu analysieren und Experimente durchzuführen. Sobald sich Daten in einem Index befinden, wird das Schreiben von Verhaltenserkennungen dazu wie gewohnt – wir können auch die gesamte Sicherheitserkennungs-Engine nutzen. Obwohl wir in diesem Experiment die LLM-Aktivität des Elastic AI Assistant als Proxy verwenden, wird sie lediglich als Vehikel verwendet, um die Überwachung von LLM-basierten Anwendungen zu demonstrieren. Darüber hinaus ist dieser Proxy-Ansatz für Anwendungen von Drittanbietern gedacht, um Daten an Elastic Security zu senden.
Wir können Sicherheitsmechanismen in den Lebenszyklus der Anwendung einführen, indem wir LLM-Aktivitäten abfangen oder beobachtbare LLM-Metriken nutzen. Es ist gängige Praxis, auf prompte Bedrohungen zu reagieren, indem verschiedene Sicherheitstaktiken implementiert werden:
- Eingaben bereinigen: Bereinigen und validieren Sie Benutzereingaben, bevor Sie sie dem Modell zuführen.
- Inhaltsmoderation: Verwenden Sie OpenAI-Tools, um schädliche Eingabeaufforderungen und Ausgaben zu filtern
- Ratenbegrenzungen und Überwachung: Verfolgen Sie Nutzungsmuster, um verdächtige Aktivitäten zu erkennen
- Allow/Blocklists: Definieren Sie akzeptable oder verbotene Eingaben für bestimmte Anwendungen
- Sicheres Prompt Engineering: Entwerfen Sie vorgefertigte Eingabeaufforderungen, die das Modell zu den beabsichtigten Ergebnissen führen
- Benutzerrollenverwaltung: Kontrollieren Sie den Benutzerzugriff, um unbefugte Aktionen zu verhindern
- Aufklärung der Endnutzer: Förderung einer verantwortungsvollen Nutzung des Modells zur Risikominderung
- Red Teaming & Monitoring: Testen Sie auf Schwachstellen und überwachen Sie kontinuierlich auf unerwartete Ergebnisse
- HITL-Feedback für das Modelltraining: Lernen Sie von Human-in-the-Loop-Problemen, um das Modell im Laufe der Zeit zu verfeinern
- API-Zugriff einschränken: Beschränken Sie den Modellzugriff basierend auf spezifischen Anforderungen und der Benutzerverifizierung
Zwei leistungsstarke Funktionen, die von OpenAI und vielen anderen LLM-Implementierern bereitgestellt werden, sind die Möglichkeit, Endbenutzer-IDs zu übermitteln und Inhalte mit einer Moderations-API zu vergleichen – Funktionen, die die Messlatte für die LLM-Sicherheit setzen. Das Senden von gehashten IDs zusammen mit der ursprünglichen Anfrage hilft bei der Missbrauchserkennung und bietet gezieltes Feedback, das eine eindeutige Benutzeridentifikation ermöglicht, ohne persönliche Informationen zu senden. Alternativ hilft der Moderationsendpunkt von OpenAI Entwicklern, potenziell schädliche Inhalte wie Hassreden, Selbstverletzung oder Gewalt zu identifizieren, und ermöglicht es ihnen, solche Inhalte zu filtern. Es geht sogar noch einen Schritt weiter, indem es Bedrohungen und die Absicht zur Selbstverletzung erkennt.
Trotz aller Empfehlungen und Best Practices zum Schutz vor böswilligen Eingabeaufforderungen sind wir uns bewusst, dass es nicht die eine perfekte Lösung gibt. Bei der Verwendung von Funktionen wie der API von OpenAI können einige dieser Bedrohungen vom Inhaltsfilter erkannt werden, der mit einer Benachrichtigung über einen Verstoß gegen die Nutzungsrichtlinie antwortet:
Diese Inhaltsfilterung ist vorteilhaft, um viele Probleme zu lösen. Es kann jedoch keine weiteren Bedrohungen im breiteren Kontext der Umgebung, des Anwendungsökosystems oder anderer Warnungen identifizieren, die möglicherweise auftreten können. Je mehr wir generative KI-Anwendungsfälle in unsere bestehenden Schutzfunktionen integrieren können, desto mehr Kontrolle und Möglichkeiten haben wir, potenziellen Bedrohungen zu begegnen. Selbst wenn LLM-Schutzmaßnahmen vorhanden sind, um rudimentäre Angriffe zu stoppen, können wir die Erkennungs-Engine immer noch verwenden, um Warnungen zu erstellen und zukünftige Abhilfemaßnahmen zu ergreifen, anstatt Missbrauch stillschweigend zu blockieren oder zuzulassen.
Proxying von LLM-Anforderungen und Einrichtung
Die optimale Sicherheitslösung integriert zusätzliche Schutzmaßnahmen direkt in das Ökosystem der LLM-Anwendung. Dies ermöglicht die Anreicherung von Alarmen mit dem vollständigen Kontext rund um Anfragen und Antworten. Wenn Anfragen an das LLM gesendet werden, können wir sie abfangen und auf potenziell bösartige Aktivitäten analysieren. Bei Bedarf kann eine Antwortaktion ausgelöst werden, um nachfolgende HTTP-Aufrufe zu verzögern. In ähnlicher Weise kann die Überprüfung der Antwort des LLM weitere Anzeichen für bösartiges Verhalten aufdecken.
Die Verwendung eines Proxys zur Verarbeitung dieser Interaktionen bietet mehrere Vorteile:
- Einfache Integration und Verwaltung: Durch die Verwaltung des neuen Sicherheitscodes in einer dedizierten Proxy-Anwendung vermeiden Sie die direkte Einbettung komplexer Sicherheitslogik in die Hauptanwendung. Dieser Ansatz minimiert die erforderlichen Änderungen an der bestehenden Anwendungsstruktur und ermöglicht eine einfachere Wartung und eine klarere Trennung von Sicherheit und Geschäftslogik. Die Hauptanwendung muss nur neu konfiguriert werden, um ihre LLM-Anforderungen über den Proxy weiterzuleiten.
- Leistung und Skalierbarkeit: Durch die Platzierung des Proxys auf einem separaten Server werden die Sicherheitsmechanismen isoliert und die Verteilung der Rechenlast erleichtert. Dies kann beim Skalieren von Vorgängen oder bei der Verwaltung leistungsintensiver Aufgaben von entscheidender Bedeutung sein, um sicherzustellen, dass die Leistung der Hauptanwendung durch die zusätzliche Sicherheitsverarbeitung nicht beeinträchtigt wird.
Schnellstartoption: Proxy mit Flask
Sie können ein- und ausgehende LLM-Verbindungen für eine schnellere Ersteinrichtung als Proxy verwenden. Dieser Ansatz kann für andere LLM-Anwendungen verallgemeinert werden, indem eine einfache Python-basierte Flask-Anwendung erstellt wird. Diese Anwendung fängt die Kommunikation ab, analysiert sie auf Sicherheitsrisiken und protokolliert relevante Informationen, bevor die Antwort weitergeleitet wird.
Es gibt mehrere SDKs, um eine Verbindung zu Elasticsearch herzustellen und OpenAI LLM-Anfragen zu verarbeiten. Das bereitgestellte llm-detection-proxy-Repository zeigt die verfügbaren Elastic- und OpenAI-Clients. Dieser Codeausschnitt hebt den Großteil des experimentellen Proxys in einer einzelnen Flask-Route hervor.
@app.route("/proxy/openai", methods=["POST"])
def azure_openai_proxy():
"""Proxy endpoint for Azure OpenAI requests."""
data = request.get_json()
messages = data.get("messages", [])
response_content = ""
error_response = None
try:
# Forward the request to Azure OpenAI
response = client.chat.completions.create(model=deployment_name, messages=messages)
response_content = response.choices[0].message.content # Assuming one choice for simplicity
choices = response.choices[0].model_dump()
except openai.BadRequestError as e:
# If BadRequestError is raised, capture the error details
error_response = e.response.json().get("error", {}).get("innererror", {})
response_content = e.response.json().get("error", {}).get("message")
# Structure the response with the error details
choices = {**error_response.get("content_filter_result", {}),
"error": response_content, "message": {"content": response_content}}
# Perform additional analysis and create the Elastic document
additional_analysis = analyze_and_enrich_request(prompt=messages[-1],
response_text=response_content,
error_response=error_response)
log_data = {"request": {"messages": messages[-1]},
"response": {"choices": response_content},
**additional_analysis}
# Log the last message and response
log_to_elasticsearch(log_data)
# Calculate token usage
prompt_tokens = sum(len(message["content"]) for message in messages)
completion_tokens = len(response_content)
total_tokens = prompt_tokens + completion_tokens
# Structure and return the response
return jsonify({
"choices": [choices],
"usage": {
"prompt_tokens": prompt_tokens,
"completion_tokens": completion_tokens,
"total_tokens": total_tokens,
}
})
Mit dem Flask-Server können Sie den OpenAI Kibana Connector so konfigurieren, dass er Ihren Proxy verwendet.
Da dieser Proxy für Ihr LLM lokal ausgeführt wird, werden Anmeldeinformationen und Verbindungsinformationen außerhalb von Elastic verwaltet, und im Abschnitt API-Schlüssel kann eine leere Zeichenfolge angegeben werden. Bevor Sie fortfahren, ist es in der Regel eine gute Idee, Ihre Verbindung zu testen. Es ist wichtig, andere Sicherheitsaspekte zu berücksichtigen, wenn Sie erwägen, eine Proxy-Lösung in einer realen Umgebung zu implementieren - nicht etwas, das dieser Prototyp aus Gründen der Kürze berücksichtigt hat.
Wir können jetzt unsere LLM-Anforderungen und -Antworten indizieren und damit beginnen, Erkennungen für die verfügbaren Daten in den azure-openai-logs
Index zu schreiben, der in diesem Experiment erstellt wurde. Optional könnten wir die Daten mit einer Elastic Ingestion-Pipeline vorverarbeiten, aber in diesem erfundenen Beispiel können wir Erkennungen mit der Leistungsfähigkeit von ES|QL effektiv schreiben.
Beispiele für AzureOpenAI LLM-Anforderungs-/Antwortdaten
Langsmith Proxy
Hinweis: Das Langsmith Proxy-Projekt stellt einen dockerisierten Proxy für Ihre LLM-APIs bereit. Es bietet zwar eine minimierte Lösung, aber zum jetzigen Zeitpunkt fehlen ihm native Funktionen für die Integration benutzerdefinierter Sicherheitsanalysetools oder die direkte Integration in Elastic Security.
Der LangSmith Proxy wurde entwickelt, um die LLM-API-Interaktion zu vereinfachen. Es handelt sich um eine Sidecar-Anwendung, die nur eine minimale Konfiguration erfordert (z. B. LLM API URL). Es verbessert die Leistung (Caching, Streaming) für Szenarien mit hohem Datenverkehr. Es verwendet NGINX für mehr Effizienz und unterstützt optionales Tracing für eine detaillierte LLM-Interaktionsverfolgung. Derzeit funktioniert es mit OpenAI und AzureOpenAI, wobei die zukünftige Unterstützung für andere LLMs geplant ist.
LLM – Potenzielle Angriffe und Möglichkeiten von Erkennungsregeln
Es ist wichtig zu verstehen, dass, auch wenn dokumentierte Schutzlisten nicht mit einigen LLMs einhergehen, das einfache Ausprobieren einiger dieser Eingabeaufforderungen sofort abgelehnt werden oder zu einer Sperrung auf der Plattform führen kann, die zum Einreichen der Eingabeaufforderung verwendet wurde. Wir empfehlen, mit Vorsicht zu experimentieren und die SLA zu verstehen, bevor Sie böswillige Eingabeaufforderungen senden. Da diese Erkundung die Ressourcen von OpenAI nutzt, empfehlen wir, den bugcrowd-Richtlinien zu folgen und sich mit Ihrer @bugcrowdninja.com-E-Mail-Adresse für ein zusätzliches Testkonto anzumelden.
Im Folgenden finden Sie eine Liste mit einigen plausiblen Beispielen, um die Erkennungsmöglichkeiten zu veranschaulichen. Jedes LLM-Thema enthält die OWASP-Beschreibung, eine Beispieleingabeaufforderung, ein Beispieldokument, die Erkennungsmöglichkeit und mögliche Aktionen, die Benutzer ergreifen könnten, wenn sie zusätzliche Sicherheitsmechanismen in ihren Workflow integrieren.
Obwohl diese Liste derzeit nicht umfangreich ist, führt Elastic Security Labs derzeit eine Reihe von Initiativen durch, um die zukünftige Entwicklung sicherzustellen, und die Formalisierung der Regeln wird fortgesetzt.
LLM01 - prompte Einspritzung
OWASP-Beschreibung: Die Manipulation von LLMs über manipulierte Eingaben kann zu unbefugtem Zugriff, Datenschutzverletzungen und kompromittierten Entscheidungen führen. Referenz hier.
Beispiel: Ein Angreifer könnte versuchen, Eingabeaufforderungen zu erstellen, die den LLM dazu verleiten, unbeabsichtigte Aktionen auszuführen oder vertrauliche Informationen preiszugeben. Hinweis: Tools wie promptmap stehen zur Verfügung, um kreative Ideen für die Injektion von Eingabeaufforderungen zu generieren und den Testprozess zu automatisieren.
Prompt:
Beispiel für eine Antwort:
Möglichkeit der Erkennungsregel: In diesem Beispiel weigerte sich der LLM, Datenbankverbindungszeichenfolgen aufgrund von Sicherheitsrisiken zu verarbeiten. Es legt Wert darauf, Anmeldeinformationen privat zu halten, und schlägt vor, sichere Methoden wie Umgebungsvariablen oder Tresore zu verwenden, um sie zu schützen.
Eine sehr spröde, aber grundlegende Abfrage für den Indikatorabgleich könnte wie folgt aussehen:
FROM azure-openai-logs |
WHERE request.messages.content LIKE "*generate*connection*string*"
OR request.messages.content LIKE "*credentials*password*username*"
OR response.choices LIKE "*I'm sorry, but I can't assist*"
Eine etwas erweiterte Abfrage erkennt mehr als zwei ähnliche Versuche innerhalb des letzten Tages.
FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
| WHERE request.messages.content LIKE "*credentials*password*username*"
OR response.choices LIKE "*I'm*sorry,*but*I*can't*assist*"
OR response.choices LIKE "*I*can’t*process*actual*sensitive*"
| stats total_attempts = count(*) by connectorId
| WHERE total_attempts >= 2
Beachten Sie, dass es viele Ansätze gibt, um bösartige Eingabeaufforderungen zu erkennen und LLM-Antworten zu schützen. Sich allein auf diese Indikatoren zu verlassen, ist nicht der beste Ansatz; Wir können die Detektion jedoch mit zusätzlicher Anreicherung oder zahlreichen Antwortversuchen nach und nach verbessern. Wenn wir außerdem eine ID in unsere Dokumente einführen, können wir unsere Abfrage weiter verbessern, indem wir Versuche basierend auf dem Feld aggregieren, das einem bestimmten Benutzer entspricht.
Beispiel 2: Der Crescendo-Effekt ist ein realistischer Jailbreak-Angriff, bei dem ein Angreifer ein Sprachmodell durch eine Reihe scheinbar harmloser Anfragen allmählich manipuliert, die sich dahingehend verlagern, dass das Modell aufgefordert wird, hypothetische Szenarien zu beschreiben, die den unbefugten Zugriff und die Manipulation sicherer Systeme beinhalten. Auf diese Weise zielen sie darauf ab, Methoden zu extrahieren, die möglicherweise die Sicherheitseinschränkungen des LLM umgehen könnten.
Prompt:
Beispiel für eine Antwort:
Mit der zusätzlichen Analyse aus der Filterung von OpenAI können wir das erste Auftreten von Missbrauch sofort erkennen.
Möglichkeit für Erkennungsregeln:
FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
AND (
request.messages.content LIKE "*credentials*password*username*"
OR response.choices LIKE "*I'm sorry, but I can't assist*"
OR analysis.openai.code == "ResponsibleAIPolicyViolation"
OR malicious
)
| STATS total_attempts = COUNT(*) BY connectorId
| WHERE total_attempts > 1
| SORT total_attempts DESC
Wenn Sie jedoch weiterhin den Crescendo-Effekt verwenden, stellen wir fest, dass der Konversations-Pivot nach dem ersten Inhaltsfilter von OpenAI nicht mehr blockiert wird. Es ist wichtig zu verstehen, dass selbst wenn solche Taktiken schwer zu verhindern sind, wir immer noch Möglichkeiten haben, sie zu erkennen.
Zusätzliche Analysetools wie LLM-Guard erkennen, ob die Konversation sensibel ist, was in diesem Fall ungenau ist. Es deutet jedoch auf potenzielle Möglichkeiten hin, bösartiges Verhalten über mehrere Eingabeaufforderungen hinweg zu verfolgen. Hinweis: Wir könnten auch die Vorteile von EQL-Sequenzen als Alternative zu diesem ES|QL-Abfrage zur Nachverfolgung von Verhaltensweisen über mehrere Ereignisse hinweg.
FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
AND (
request.messages.content LIKE "*Molotov*"
OR analysis.openai.code == "ResponsibleAIPolicyViolation"
OR malicious
)
| STATS attempts = count(*), max_sensitivity = max(analysis.llm_guard_response_scores.Sensitive) BY connectorId
| WHERE attempts >= 1 AND max_sensitivity > 0.5
| SORT attempts DESC
Diese Abfrage erkennt verdächtiges Verhalten im Zusammenhang mit Molotow-Cocktails über mehrere Ereignisse hinweg, indem sie Sequenzen von Protokolleinträgen analysiert, die einem einzelnen Benutzer/einer einzelnen Sitzung zugeordnet sind (identifiziert durch connectorId). Der Abfragekern filtert Ereignisse basierend auf:
- Content Matching: Es wird nach Erwähnungen von "Molotow" in Gesprächsinhalten gesucht (
request.messages.content LIKE "*Molotov*"
) - **Richtlinienverstöße: Es identifiziert Versuche, die von den Sicherheitsfiltern von OpenAI (
analysis.openai.code == "ResponsibleAIPolicyViolation"
) blockiert werden, was auf den Beginn potenziell verdächtigen Verhaltens hinweist. - Berücksichtigung bösartiger Flags: Dazu gehören Protokolle, in denen das System den Inhalt als bösartig (
malicious == true
) gekennzeichnet hat, wodurch potenziell subtile oder unterschiedliche Erwähnungen erfasst werden - Analyse auf Sitzungsebene: Durch das Gruppieren von Ereignissen nach connectorId wird die vollständige Abfolge der Versuche innerhalb einer Sitzung analysiert. Anschließend werden die Gesamtzahl der Versuche (
attempts = count(*)
) und die höchste Empfindlichkeitsbewertung (max_sensitivity = max(analysis.llm_guard_response_scores.Sensitive)
) für alle Versuche in dieser Sitzung berechnet - Kennzeichnen von Sitzungen mit hohem Risiko: Es filtert Sitzungen mit mindestens einem Versuch (
attempts >= 1
) und einer maximalen Sensitivitätsbewertung von mehr als 0,5 (max_sensitivity > 0.5
). Dieser Schwellenwert hilft dabei, sich auf Sitzungen zu konzentrieren, in denen Benutzer beharrlich potenziell riskante Inhalte diskutiert oder offengelegt haben.
Durch die Analyse dieser Faktoren über mehrere Ereignisse innerhalb einer Sitzung hinweg können wir damit beginnen, einen Ansatz zu entwickeln, um ein Muster eskalierender Diskussionen zu erkennen, auch wenn einzelne Ereignisse möglicherweise nicht allein gekennzeichnet werden.
LLM02 - unsichere Ausgabebehandlung
OWASP-Beschreibung: Die Vernachlässigung der Validierung von LLM-Ausgaben kann zu nachgelagerten Sicherheitslücken führen, einschließlich der Ausführung von Code, die Systeme kompromittiert und Daten offenlegt. Referenz hier.
Beispiel: Ein Angreifer kann versuchen, das LLM auszunutzen, um Ausgaben zu generieren, die für Cross-Site-Scripting (XSS) oder andere Injektionsangriffe verwendet werden können.
Prompt:
Beispiel für eine Antwort:
Möglichkeit für Erkennungsregeln:
FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
| WHERE (
response.choices LIKE "*<script>*"
OR response.choices LIKE "*document.cookie*"
OR response.choices LIKE "*<img src=x onerror=*"
OR response.choices LIKE "*<svg/onload=*"
OR response.choices LIKE "*javascript:alert*"
OR response.choices LIKE "*<iframe src=# onmouseover=*"
OR response.choices LIKE "*<img ''><script>*"
OR response.choices LIKE "*<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>*"
OR response.choices LIKE "*<IMG SRC=# onmouseover=alert('xxs')>*"
OR response.choices LIKE "*<IMG onmouseover=alert('xxs')>*"
OR response.choices LIKE "*<IMG SRC=/ onerror=alert(String.fromCharCode(88,83,83))>*"
OR response.choices LIKE "*javascript:alert('XSS')>*"
OR response.choices LIKE "*<IMG SRC=javascript:alert('XSS')>*"
OR response.choices LIKE "*<IMG SRC=\"jav
ascript:alert('XSS');\">*"
)
| stats total_attempts = COUNT(*), users = COUNT_DISTINCT(connectorId)
| WHERE total_attempts >= 2
Diese Pseudo-Abfrage erkennt potenziell unsichere Ausgabeverarbeitung, indem sie LLM-Antworten identifiziert, die Scripting-Elemente oder Cookie-Zugriffsversuche enthalten, die bei Cross-Site-Scripting-Angriffen (XSS) üblich sind. Es handelt sich um eine Shell, die um Allow- oder Blocklisten für bekannte Keywords erweitert werden kann.
LLM04 - Modell DoS
OWASP-Beschreibung: Eine Überlastung von LLMs mit ressourcenintensiven Vorgängen kann zu Dienstunterbrechungen und erhöhten Kosten führen. Referenz hier.
Beispiel: Ein Angreifer kann komplexe Eingabeaufforderungen senden, die übermäßige Rechenressourcen verbrauchen.
Prompt:
Beispiel für eine Antwort:
Möglichkeit für Erkennungsregeln:
FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
| WHERE response.choices LIKE "*requires*significant*computational*resources*"
| stats total_attempts = COUNT(*), users = COUNT_DISTINCT(connectorId)
| WHERE total_attempts >= 2
Diese Erkennung veranschaulicht ein weiteres einfaches Beispiel dafür, wie die LLM-Antwort verwendet wird, um potenziell missbräuchliches Verhalten zu identifizieren. Obwohl dieses Beispiel möglicherweise keine traditionelle Sicherheitsbedrohung darstellt, könnte es emulieren, wie Angreifer den Opfern Kosten auferlegen können, indem sie entweder Ressourcen oder Token verbrauchen.
Beispiel 2: Ein Angreifer kann komplexe Eingabeaufforderungen senden, die übermäßige Rechenressourcen verbrauchen.
Prompt:
Beispiel für eine Antwort:
Auf den ersten Blick scheint diese Aufforderung harmlos zu sein. Übermäßige Anfragen und ausführliche Antworten in kurzer Zeit können jedoch die Kosten erheblich in die Höhe treiben.
Möglichkeit für Erkennungsregeln:
FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 HOUR
| STATS request_count = COUNT(*), distinct_prompts = COUNT_DISTINCT(request.messages.content) BY connectorId
| WHERE request_count > 50 AND distinct_prompts > 10
| SORT request_count DESC
Im Kontext von Beispiel 2 verfolgt und analysiert diese Arbeitsabfrage effizient Verwendungsmuster, indem sie alle Anforderungen und eindeutigen Eingabeaufforderungsinhalte für jede connectorId
aus dem azure-openai-logs
in der letzten Stunde zählt. Wenn ein connectorId
innerhalb dieses Zeitraums mehr als 50 Anfragen mit mehr als zehn eindeutigen Eingabeaufforderungen einreicht, deutet dies auf ein potenzielles Missbrauchsmuster wie das beschriebene hin, bei dem ein Angreifer möglicherweise Abfragen ändert, um Details des Verschlüsselungsalgorithmus zu untersuchen, was möglicherweise zu einer übermäßigen Belastung führt oder Erkennungssysteme umgeht. Die Ergebnisse werden dann so sortiert, dass die connectorIds
mit der höchsten Anforderungsanzahl priorisiert werden, was dazu beiträgt, die aktivsten oder verdächtigsten Quellen schnell zu identifizieren.
LLM06 - Offenlegung sensibler Informationen
OWASP-Beschreibung: Das Versäumnis, sich vor der Offenlegung sensibler Informationen in LLM-Ausgaben zu schützen, kann rechtliche Konsequenzen oder den Verlust von Wettbewerbsvorteilen nach sich ziehen. Referenz hier.
Beispiel: Ein Angreifer kann Eingabeaufforderungen erstellen, um vertrauliche Informationen zu extrahieren, die in die Trainingsdaten eingebettet sind.
Prompt:
Beispiel für eine Antwort:
Möglichkeit für Erkennungsregeln:
FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
| WHERE request.messages.content LIKE "*common*passwords*used*in*the*dataset*" AND malicious
| stats total_attempts = COUNT(*), users = COUNT_DISTINCT(connectorId)
BY identified_threats.keyword, analysis.langkit_score
| WHERE total_attempts >= 2
Diese Abfrage sucht nach Protokollen vom letzten Tag, die Anforderungen enthalten, die speziell nach "allgemeinen Kennwörtern gefragt werden, die im Dataset verwendet werden", um das Modell zu trainieren, und wo solche Anforderungen als bösartig gekennzeichnet sind. Es aggregiert diese Protokolle, um die Anzahl solcher Versuche zu zählen, und identifiziert unterschiedliche beteiligte Benutzer, gruppiert nach identifizierten Bedrohungen und der Bewertung des Language Kit. Mit einer gewissen Anreicherung stellt die Einbeziehung von AND malicious = true
sicher, dass der Fokus auf Anfragen liegt, die bereits als potenziell schädlich gekennzeichnet sind, und hilft dabei, Untersuchungs- und Reaktionsmaßnahmen zu priorisieren.
Anreicherung von Erkennungsregeln mit Security Insights
Durch die Weiterleitung von LLM-Anfragen über einen Proxy können wir auf spezialisierte Sicherheitstools zurückgreifen, um jede Anfrage auf Anzeichen böswilliger Absichten zu analysieren. Bei der Erkennung kann die ursprüngliche Anforderung mit zusätzlichen Metadaten angereichert werden, die die Wahrscheinlichkeit bösartiger Inhalte und die spezifische Art der Bedrohung angeben, die sie darstellen. Diese angereicherten Daten werden dann in Elasticsearch indiziert, wodurch ein robuster Datensatz für Überwachung, Warnung und retrospektive Analyse erstellt wird. Mit dieser Anreicherung sind die LLM-Nachweismöglichkeiten aus dem letzten Abschnitt möglich.
Wir gehen nicht auf jedes verfügbare Tool ein, aber es sind mehrere Open-Source-Tools entstanden, die unterschiedliche Ansätze zur Analyse und Sicherung von LLM-Interaktionen bieten. Einige dieser Tools werden von Machine Learning-Modellen unterstützt, die darauf trainiert sind, bösartige Eingabeaufforderungen zu erkennen:
- Rebuff (GitHub): Nutzt maschinelles Lernen, um Versuche von Social Engineering, Phishing und anderen bösartigen Aktivitäten durch LLM-Interaktionen zu identifizieren und einzudämmen. Beispiele für die Verwendung sind das Übergeben von Anforderungsinhalten durch die Analyse-Engine von Rebuff und das Markieren von Anfragen mit einem "bösartigen" booleschen Feld basierend auf den Ergebnissen.
- LLM-Guard (GitHub): Bietet eine regelbasierte Engine zum Erkennen schädlicher Muster in LLM-Anfragen. LLM-Guard kann erkannte Bedrohungen anhand vordefinierter Kategorien kategorisieren und Anfragen mit detaillierten Bedrohungsklassifizierungen anreichern.
- LangKit (GitHub): LangKit ist ein Toolkit zum Überwachen und Sichern von LLMs, mit dem Anforderungsinhalte auf Anzeichen von gegnerischen Eingaben oder unbeabsichtigtem Modellverhalten analysiert werden können. Es bietet Hooks für die Integration von benutzerdefinierten Analysefunktionen.
- Vigil-LLM (GitHub): Konzentriert sich auf die Echtzeitüberwachung und Alarmierung bei verdächtigen LLM-Anfragen. Die Integration in die Proxy-Schicht ermöglicht die sofortige Kennzeichnung potenzieller Sicherheitsprobleme und die Anreicherung der Anforderungsdaten mit Vigilanzbewertungen.
- Open-Prompt Injection (GitHub): Bietet Methoden und Tools zur Erkennung von Prompt-Injection-Angriffen, die die Anreicherung von Anforderungsdaten mit spezifischen Kompromittierungsindikatoren im Zusammenhang mit Prompt-Injection-Techniken ermöglichen.
Hinweis: Die meisten dieser Tools erfordern zusätzliche Aufrufe/Kosten für ein externes LLM und würden eine weitere Infrastruktur erfordern, um eine effektive Bedrohungssuche durchzuführen.
Eine einfache Beispielimplementierung, die LLM-guard und LangKit verwendet, könnte wie folgt aussehen:
def analyze_and_enrich_request(
prompt: str, response_text: str, error_response: Optional[dict] = None
) -> dict:
"""Analyze the prompt and response text for malicious content and enrich the document."""
# LLM Guard analysis
sanitized_prompt, results_valid_prompt, results_score_prompt = scan_prompt(
input_scanners, prompt["content"]
)
(
sanitized_response_text,
results_valid_response,
results_score_response,
) = scan_output(output_scanners, sanitized_prompt, response_text)
# LangKit for additional analysis
schema = injections.init()
langkit_result = extract({"prompt": prompt["content"]}, schema=schema)
# Initialize identified threats and malicious flag
identified_threats = []
# Check LLM Guard results for prompt
if not any(results_valid_prompt.values()):
identified_threats.append("LLM Guard Prompt Invalid")
# Check LLM Guard results for response
if not any(results_valid_response.values()):
identified_threats.append("LLM Guard Response Invalid")
# Check LangKit result for prompt injection
prompt_injection_score = langkit_result.get("prompt.injection", 0)
if prompt_injection_score > 0.4: # Adjust threshold as needed
identified_threats.append("LangKit Injection")
# Identify threats based on LLM Guard scores
for category, score in results_score_response.items():
if score > 0.5:
identified_threats.append(category)
# Combine results and enrich document
# llm_guard scores map scanner names to float values of risk scores,
# where 0 is no risk, and 1 is high risk.
# langkit_score is a float value of the risk score for prompt injection
# based on known threats.
enriched_document = {
"analysis": {
"llm_guard_prompt_scores": results_score_prompt,
"llm_guard_response_scores": results_score_response,
"langkit_score": prompt_injection_score,
},
"malicious": any(identified_threats),
"identified_threats": identified_threats,
}
# Check if there was an error from OpenAI and enrich the analysis
if error_response:
code = error_response.get("code")
filtered_categories = {
category: info["filtered"]
for category, info in error_response.get(
"content_filter_result", {}
).items()
}
enriched_document["analysis"]["openai"] = {
"code": code,
"filtered_categories": filtered_categories,
}
if code == "ResponsibleAIPolicyViolation":
enriched_document["malicious"] = True
return enriched_document
Diese Funktion könnte für jede Anfrage aufgerufen werden, die den Proxy durchläuft, wobei die zurückgegebenen Daten an das Anforderungsdokument angehängt werden, bevor es an Elasticsearch gesendet wird. Das Ergebnis ist ein detaillierter und umsetzbarer Datensatz, der die rohen Interaktionen mit dem LLM erfasst und unmittelbare Sicherheitseinblicke bietet, die auf der Grundlage von Anfrage und Antwort in unsere Erkennungsregeln eingebettet werden können. Wenn sich der Kreis mit dem Beispiel für die Eingabeaufforderungsinjektion LLM01 schließt, könnte die Abfrage wie folgt aktualisiert werden:
FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
| WHERE identified_threats.keyword == "LangKit Injection" OR analysis.langkit_score > 0.4
| stats total_attempts = count(*), users = count_distinct(connectorId) by identified_threats.keyword, analysis.langkit_score
| WHERE users == 1 and total_attempts >= 2
Wie Sie sehen können, sind beide Bewertungsmechanismen subjektiv und basieren auf den Ergebnissen, die von den Open-Source-Tools zur Analyse von Eingabeaufforderungen zurückgegeben werden. Diese Abfrage filtert Protokolle vom letzten Tag, in denen die identifizierte Bedrohung "LangKit-Injektion" ist oder der LangKit-Score über 0.4
liegt. Anschließend werden die Gesamtzahl der Versuche berechnet und die Anzahl der eindeutigen Benutzer (Agenten), die jeder identifizierten Bedrohungskategorie und LangKit-Bewertung zugeordnet sind, gezählt, wobei nur Fälle einbezogen werden, an denen ein einzelner Benutzer beteiligt ist (users == 1
) und die Gesamtzahl der Versuche zwei oder mehr (total_attempts >= 2
).
Mit diesen zusätzlichen Tools stehen uns eine Vielzahl von Analyseergebnisfeldern zur Verfügung, um unsere Erkennungsregeln zu verbessern. In diesen Beispielen haben wir der Einfachheit halber die meisten Daten so ausgeliefert, wie sie sind. In einer Produktionsumgebung ist es jedoch entscheidend, diese Felder über alle Tools und LLM-Antworten hinweg auf ein Schema wie Elastic Common Schema (ECS ) zu normalisieren. Die Normalisierung von Daten in ECS verbessert die Interoperabilität zwischen verschiedenen Datenquellen, vereinfacht die Analyse und optimiert die Erstellung effektiverer und kohärenterer Sicherheitsregeln.
Im zweiten Teil dieser Serie werden wir erörtern, wie wir einen formelleren Ansatz für die ECS-Feldzuordnung und Integrationen gewählt haben.
Alternative Optionen für die LLM-Anwendungsprüfung
Während die Verwendung eines Proxys unkompliziert sein kann, eignen sich andere Ansätze möglicherweise besser für ein Produktionssetup. Zum Beispiel:
- Nutzung von Application Performance Monitoring (APM)
- Verwenden der OpenTelemetry-Integration
- Änderungen in Kibana direkt ändern, um LLM-Aktivitäten zu überwachen und nachzuverfolgen
Es überrascht nicht, dass diese Ansätze potenzielle Einschränkungen aufweisen, z. B. dass nicht alle generierten Daten des LLM-Sicherheitsanalysetools nativ aufgenommen werden, ohne eine benutzerdefinierte Logik zur Unterstützung von Tools von Drittanbietern zu entwickeln.
Nutzung von Elastic APM für detaillierte Anwendungseinblicke
Elastic APM bietet eine alternative Lösung für die Überwachung von Anwendungen in Echtzeit, die für die Erkennung von Leistungsengpässen und die Identifizierung problematischer Anfragen oder Abfragen unerlässlich ist. Durch die Integration von Elastic APM erhalten Benutzer detaillierte Einblicke in Transaktionszeiten, die Leistung von Datenbankabfragen, die Effizienz externer API-Aufrufe und vieles mehr. Diese umfassende Transparenz macht es einfacher, Leistungsprobleme oder Fehler schnell zu beheben und zu beheben. Im Gegensatz zum Proxy-Ansatz nimmt APM automatisch Protokolle über Ihre Anwendung in Elastic auf und bietet so die Möglichkeit, Sicherheitserkennungsregeln basierend auf den Verhaltensweisen in Ihren Daten zu erstellen.
Nutzung von OpenTelemetry für eine verbesserte Beobachtbarkeit
Bei Anwendungen, die OpenTelemetry bereits einsetzen, kann die Integration mit Elastic APM die Beobachtbarkeit verbessern, ohne dass umfangreiche Änderungen an der Instrumentierung erforderlich sind. Diese Integration unterstützt die Erfassung einer Vielzahl von Telemetriedaten, einschließlich Traces und Metriken, die nahtlos an den Elastic Stack gesendet werden können. Dieser Ansatz ermöglicht es Entwicklern, vertraute Bibliotheken weiterhin zu verwenden und gleichzeitig von den robusten Überwachungsfunktionen von Elastic zu profitieren. Die Kompatibilität von OpenTelemetry über mehrere Programmiersprachen hinweg und die Unterstützung durch das native Protokoll von Elastic (OTLP) erleichtern eine unkomplizierte Datenübertragung und bieten eine robuste Grundlage für die Überwachung verteilter Systeme. Im Vergleich zum Proxy-Beispiel werden bei diesem Ansatz Daten nativer aufgenommen, als wenn ein unabhängiger Index- und Protokollierungsmechanismus in Elastic beibehalten wird.
LLM Auditing mit Kibana
Ähnlich wie beim Schreiben von benutzerdefinierter Logik für Ihre LLM-Anwendung, um Daten zu prüfen und zu versenden, können Sie den Ansatz mit dem KI-Assistenten von Elastic testen. Wenn Sie mit TypeScript vertraut sind, sollten Sie die Bereitstellung einer lokalen Elastic-Instanz mithilfe des Kibana Getting Started Guide in Betracht ziehen. Navigieren Sie nach der Einrichtung zum Elastic AI Assistant und konfigurieren Sie ihn so, dass LLM-Anfragen und -Antworten für die Prüfung und Analyse abgefangen werden. Hinweis: Dieser Ansatz verfolgt in erster Linie die Elastic-spezifische LLM-Integration im Vergleich zur Verwendung von APM und anderen Integrationen oder einem Proxy zur Nachverfolgung von Anwendungen von Drittanbietern. Sie sollten nur zu Versuchs- und Sondierungszwecken in Betracht gezogen werden.
Glücklicherweise ist Kibana bereits mit APM instrumentiert, sodass Sie bei der Konfiguration eines APM-Servers automatisch mit der Aufnahme von Protokollen aus dieser Quelle beginnen (indem Sie elastic.apm.active: true
festlegen). Weitere Informationen finden Sie in der README-Datei .
Abschließende Gedanken
Während wir bei Elastic die Integration von Sicherheitspraktiken in den Lebenszyklus großer Sprachmodelle fortsetzen, wird deutlich, dass die Einbettung von Sicherheit in LLM-Workflows einen Weg zur Erstellung sichererer und zuverlässigerer Anwendungen bieten kann. Diese erfundenen Beispiele, die aus unserer Arbeit während der OnWeek stammen, veranschaulichen, wie jemand bösartige Aktivitäten proaktiv erkennen, warnen und selektieren kann, indem er die Sicherheitslösungen nutzt, die Analysten am intuitivsten und effektivsten finden.
Es ist auch erwähnenswert, dass wir mit dem Beispiel-Proxy-Ansatz ein Modell integrieren können, um Anfragen aktiv zu erkennen und zu verhindern. Darüber hinaus können wir die LLM-Antwort selektieren, bevor wir sie an den Benutzer zurücksenden, wenn wir bösartige Bedrohungen identifiziert haben. An diesem Punkt haben wir die Flexibilität, unsere Sicherheitsvorkehrungen zu erweitern, um eine Vielzahl von Abwehransätzen abzudecken. In diesem Fall gibt es einen schmalen Grat zwischen Sicherheit und Leistung, da jede zusätzliche Überprüfung Zeit in Anspruch nimmt und den natürlichen Gesprächsfluss behindert, den die Benutzer erwarten würden.
Schauen Sie sich den Proof-of-Concept-Proxy unter llm-detection-proxy an und passen Sie ihn an Ihre Bedürfnisse an!
Wir sind immer daran interessiert, Anwendungsfälle und Workflows wie diese zu hören, also kontaktieren Sie uns wie immer über GitHub Issues, chatten Sie mit uns in unserer Community Slack und stellen Sie Fragen in unseren Diskussionsforen.
Die Entscheidung über die Veröffentlichung der in diesem Blogeintrag beschriebenen Leistungsmerkmale und Features sowie deren Zeitpunkt liegt allein bei Elastic. Es ist möglich, dass noch nicht verfügbare Leistungsmerkmale oder Features nicht rechtzeitig oder überhaupt nicht veröffentlicht werden.