
Detaillierte Offenlegung von CVE-2025-68664, einer kritischen Deserialisierungsschwachstelle im LangChain-Kern, die das Exfiltrieren von Geheimnissen und potenzielle RCE durch präparierte Prompts und Serialisierungsabläufe ermöglicht.
Autor: Yarden Porat
Cyata-Forschung: LangGrinch-Schwachstelle in LangChain
Veröffentlicht: https://cyata.ai/blog/langgrinch-langchain-core-cve-2025-68664/

Gestern hat LangChain eine kritische Warnung zu einer Schwachstelle veröffentlicht, die ich in langchain-core entdeckt habe: CVE-2025-68664 / GHSA-c67j-w6g6-q2cm.
Anfang dieses Jahres konzentrierte sich meine Forschung auf das Knacken von Secret-Managern in unserer Arbeit „Vault Fault“ – Systeme, die speziell als Sicherheitsgrenze um Ihre sensibelsten Anmeldedaten konzipiert sind. Eine Erkenntnis wiederholte sich immer wieder: Wenn eine Plattform von einem Angreifer kontrollierte Daten als vertrauenswürdige Struktur behandelt, bricht diese Grenze schnell zusammen. Dieses Mal ist das System, das „bricht“, nicht Ihr Secret-Manager. Es ist das Agenten-Framework, das sie nutzen kann.
Warum diese Schwachstelle besondere Aufmerksamkeit verdient:
Sie liegt im Kern. Das ist kein Fehler eines bestimmten Tools, kein Randfall einer Integration und kein „irgendein Community-Paket hat etwas Seltsames gemacht.“ Die anfälligen APIs (dumps() / dumpd()) befinden sich im langchain-core selbst.
Der Radius ist enorm. Gemessen an den Downloads ist LangChain eine der am weitesten verbreiteten KI-Framework-Komponenten weltweit. Stand Ende Dezember 2025 zeigen öffentliche Pakettelemetrien Hunderte Millionen Installationen, wobei pepy.tech ~847 Mio. Gesamtdownloads und pypistats ~98 Mio. Downloads im letzten Monat meldet.
Ein Prompt kann viele Mechanismen auslösen. Der häufigste reale Pfad ist hier nicht „der Angreifer schickt einen serialisierten Blob und Sie rufen load() auf.“ Es ist subtiler: LLM-Ausgaben können Felder wie additional_kwargs oder response_metadata beeinflussen, und diese Felder können serialisiert und später über normale Framework-Funktionen wie Streaming-Logs/Ereignisse deserialisiert werden. Einfach ausgedrückt bedeutet das, dass ein Exploit durch einen einzigen Text-Prompt ausgelöst werden kann, der zu einem unerwartet komplexen internen Pipeline wird.
Bevor Sie weiterlesen: Patches wurden bereits in den Versionen 1.2.5 und 0.3.81 veröffentlicht. Wenn Sie LangChain in der Produktion einsetzen, ist dies komplizierter als es scheint; bitte aktualisieren Sie so schnell wie möglich.
LangChain verwendet ein spezielles internes Serialisierungsformat, bei dem Wörterbücher, die den Marker 'lc' enthalten, LangChain-Objekte darstellen. Die Schwachstelle bestand darin, dass dumps() und dumpd() benutzerkontrollierte Wörterbücher, die versehentlich den reservierten Schlüssel 'lc' enthielten, nicht korrekt maskierten.
Sobald ein Angreifer also den Orchestrierungszyklus von LangChain dazu bringen kann, Inhalte einschließlich des Schlüssels 'lc' zu serialisieren und später zu deserialisieren, kann er ein unsicheres beliebiges Objekt instanziieren und möglicherweise viele angreiferfreundliche Pfade auslösen.
Die Warnung listet 12 verschiedene anfällige Abläufe auf, die in realen Anwendungsfällen wie Standard-Streaming-Ereignissen, Logging, Nachrichtenverlauf/Speicher oder Caching extrem häufig sind:

Die verheerendsten Auswirkungen umfassen:
Extraktion von Geheimnissen aus Umgebungsvariablen. Die Warnung stellt fest, dass dies bei der Deserialisierung mit secrets_from_env=True geschieht. Bemerkenswert ist, dass dies bis gestern standardmäßig aktiviert war. 🙂
Instanziierung von Objekten in vorab genehmigten Namensräumen (einschließlich langchain_core, _langchain_openai, langchain_aws, langchain_anthropic…), was möglicherweise Nebenwirkungen in Konstruktoren auslöst (Netzwerkaufrufe, Dateioperationen usw.).
Unter bestimmten Bedingungen kann die Instanziierung von LangChain-Objekten zu beliebiger Codeausführung führen.
Dies ist klassifiziert unter CWE-502: Deserialisierung nicht vertrauenswürdiger Daten, mit einem CVSS CNA-Score von 9.3 (Kritisch).
Am Heiligabend hatte ich die am wenigsten weihnachtliche Arbeit: Ich sah mir den Serialisierungscode an und fragte „Moment… warum wird das als vertrauenswürdig betrachtet?“
Sicherheitsforschung sieht von außen oft dramatisch aus. In Wirklichkeit ist es meist sorgfältiges Lesen, kleine Hypothesen und das langsame Ansammeln von „das ist seltsam“-Momenten.
Es begann, wie so vieles bei Cyata: mit einer einfachen Frage, die wir uns bei der Bewertung von KI-Stacks auf echtes Risiko immer stellen:
Wo liegen die Vertrauensgrenzen in KI-Anwendungen, und wissen die Entwickler wirklich, wo diese Grenzen liegen?
LangChain ist ein leistungsstarkes Framework, und wie die meisten modernen Frameworks muss es komplexe strukturierte Daten bewegen: Nachrichten, Tool-Aufrufe, Streaming-Ereignisse, Traces, Caches und „Runnables“.
Beim Durchsehen früherer Forschung gab es bereits umfangreiche Untersuchungen zu LangChain-Tools und Integrationen, aber sehr wenige Funde in der Kernbibliothek.
Ich begann die Forschung mit umgekehrter Vorgehensweise. Finde interessante Stellen (Senken), dann finde heraus, wie ein Angreifer sie erreichen kann. Deserialisierung war ein offensichtliches Ziel.
Ich brauchte ziemlich lange, um etwas Bedeutendes zu finden. Aber nach einiger Zeit fand ich, dass ich unter der Annahme einer angreiferkontrollierten Deserialisierungsprimitive einen blinden SSRF auslösen konnte, der zur Exfiltration von Umgebungsvariablen genutzt werden könnte (bald ausführlich beschrieben). Da das Ergebnis auf die Exfiltration von Geheimnissen beschränkt war und nicht mein Hauptziel RCE war, prüfte ich die Deserialisierung weiter und nahm mir Zeit.
Der Fehler war kein Stück schlechten Codes, es war fehlender Code. dumps() maskierte einfach keine benutzerkontrollierten Wörterbücher, die 'lc'-Schlüssel enthielten. Fehlende Maskierung im Serialisierungspfad, nicht in der Deserialisierung.

Es ist viel leichter, etwas Falsches zu bemerken, als das Fehlen von etwas zu bemerken, besonders wenn man load() prüft und nicht dumps(). In einem der am gründlichsten geprüften KI-Frameworks. Zweieinhalb Jahre.
Von dort aus wurde die Forschung zu einer strukturierten Übung:
Identifizieren, wo nicht vertrauenswürdiger Inhalt (hauptsächlich beliebige Wörterbücher) in die Serialisierung gelangt (LLM-Ausgaben, Prompt-Injection, Benutzereingabe, externe Tools, extrahierte Dokumente).
Identifizieren, wann diese serialisierten Daten deserialisiert werden.
Identifizieren, was ein Angreifer durch beliebige Objektinstanziierung erreichen kann.
Zu diesem Zeitpunkt war der Hauptfund klar und für einen verantwortungsvollen Bericht umsetzbar: Es gab eine Maskierungslücke in dumps() / dumpd() bei Wörterbüchern mit dem Schlüssel 'lc'.
Die Warnung erfasste später, was wir in der Praxis oft sehen: Felder wie additional_kwargs und response_metadata können durch LLM-Ausgabe und Prompt-Injection beeinflusst werden, und diese Felder können in vielen Abläufen serialisiert-deserialisiert werden.
Zur Ehre des LangChain-Teams: Die Reaktion und die Folgemaßnahmen waren entschlossen, nicht nur der Bug wurde gepatched, sondern auch die Standardeinstellungen wurden verschärft, die für die Welt, in der wir jetzt leben, zu permissiv waren.
Das LangChain-Projekt beschloss, eine Belohnung von 4.000 USD für diesen Fund zu vergeben. Laut huntr, der Plattform, auf der LangChain sein Bug-Bounty-Programm durchführte, wäre dies die höchste jemals im Projekt vergebene Summe, mit bisherigen Belohnungen von bis zu 125 USD.
LangChain serialisiert bestimmte Objekte mit einem strukturierten Wörterbuchformat. Der Schlüssel 'lc' wird intern verwendet, um anzuzeigen: „Dies ist eine serialisierte LangChain-Struktur“, nicht nur beliebige Benutzerdaten.
Dies ist ein häufiges Muster, aber es erzeugt eine Sicherheitsinvariante: Alle Benutzerdaten, die 'lc' enthalten könnten, müssen vorsichtig behandelt werden. Sonst könnte ein Angreifer ein Wörterbuch erstellen, das wie ein internes Objekt „aussieht“ und den Deserialisierer austrickst, ihm einen Wert zu geben.
Der Patch macht die Absicht in der aktualisierten Dokumentation explizit: Während der Serialisierung werden einfache Wörterbücher, die den Schlüssel 'lc' enthalten, maskiert, indem sie eingewickelt werden.
Dies verhindert, dass diese Wörterbücher bei der Deserialisierung mit tatsächlichen serialisierten LangChain-Objekten verwechselt werden.
Die load()/loads()-Funktionen von LangChain instanziieren keine beliebigen Klassen – sie prüfen gegen eine Whitelist, die steuert, welche Klassen deserialisiert werden dürfen. Standardmäßig umfasst diese Whitelist Klassen aus langchain_core, langchain_openai, langchain_aws und anderen Ökosystem-Paketen.
Hier ist der Haken: Die meisten Klassen in der Whitelist haben harmlose Konstruktoren. Das Finden ausnutzbarer Pfade erforderte das Durchsuchen des Ökosystems nach Klassen, die bei der Instanziierung etwas Bedeutendes tun. Die, die ich gefunden habe, sind unten detailliert beschrieben, aber es könnte andere geben, die noch entdeckt werden müssen.
Die loads()-Funktion von LangChain unterstützt einen secret-Typ, der während der Deserialisierung Werte aus Umgebungsvariablen auflöst. Vor dem Patch war diese Funktion secrets_from_env standardmäßig aktiviert:
if (
value.get("lc") == 1
and value.get("type") == "secret"
and value.get("id") is not None
):
[key] = value["id"]
if key in self.secrets_map:
return self.secrets_map[key]
if self.secrets_from_env and key in os.environ and os.environ[key]:
return os.environ[key] # <-- Rückgabe der Umgebungsvariablen
return None
Wenn das deserialisierte Objekt an den Angreifer zurückgegeben wird, z.B. als Nachrichtenverlauf innerhalb eines LLM-Kontexts, könnte das Umgebungsvariablen durchsickern lassen.
Aber der interessantere Pfad ist eine indirekte Prompt-Injection. Selbst ein Angreifer, der keine LLM-Antworten sehen kann, kann Geheimnisse exfiltrieren, indem er die richtige Klasse instanziiert. ChatBedrockConverse aus langchain_aws befindet sich sowohl in der Standard-Whitelist von loads als und führt bei der Konstruktion einen GET-Request aus. Der GET-Endpunkt wird vom Angreifer kontrolliert, und ein bestimmter HTTP-Header kann über die Funktion secrets_from_env mit einer Umgebungsvariablen gefüllt werden.

Dieser Validator wird ausgeführt, wenn ChatBedrockConverse instanziiert wird. Der Angreifer kontrolliert endpoint_url und löst einen ausgehenden Request aus. In Kombination mit secrets_from_env kann der Header aws_access_key_id mit jeder Umgebungsvariablen gefüllt werden – nicht nur mit AWS-Schlüsseln.
Wir veröffentlichen hier bewusst keinen fertigen Exploit, um den Sicherheitsteams Zeit zu geben. In einigen Monaten wird die Huntr-Seite sie automatisch veröffentlichen.
Unter den Klassen in der Standard-Whitelist von loads() befindet sich PromptTemplate. Diese Klasse erstellt einen Prompt aus einem Template, und eines der verfügbaren Template-Formate ist Jinja2.
Wenn das Template mit Jinja2 gerendert wird, kann beliebiger Python-Code ausgeführt werden. Wir haben keinen Weg gefunden, dies direkt aus der loads()-Funktion allein auszulösen, aber wenn ein späterer Aufruf des deserialisierten Objekts das Rendern auslöst, folgt die Codeausführung.
Wir vermuten, dass es Pfade zur direkten Codeausführung aus loads() geben könnte, aber wir haben noch keinen bestätigt. Wenn Sie eine solide Idee oder einen vielversprechenden Ansatz haben, freuen wir uns über Hinweise – genau hier verwandelt die Sicherheitscommunity Hypothesen in Beweise. 🤝
Ebenso erwähnenswert: In früheren Versionen war auch die Klasse Chain in der Whitelist. Diese Klasse hatte spezielle Fähigkeiten, die einen Fluss zum Rendern von Templates ermöglichen könnten.
Ihre Anwendung ist potenziell gefährdet, wenn sie anfällige Versionen von langchain-core verwendet. Hier sind einige der häufigsten anfälligen Muster (insgesamt wurden 12 Abläufe identifiziert):
Dennoch ist das Systemverhalten komplex genug, dass es riskant ist anzunehmen, ein schneller Code-Review würde jede erreichbare Variante aufdecken. Am sichersten ist es, auf die gepatchete Version zu aktualisieren und nicht anzunehmen, dass Sie sicher sind, bis Sie dies getan haben.
Die Warnung stellt auch fest, was ich für den wichtigsten Punkt in der Praxis halte:
Der häufigste Angriffsvektor erfolgt über LLM-Antwortfelder wie additional_kwargs oder response_metadata, die durch Prompt-Injection kontrolliert werden können und dann in Streaming-Operationen serialisiert/deserialisiert werden.
Genau diese Art von Überschneidung „KI trifft klassische Sicherheit“ erwischt Organisationen auf dem falschen Fuß. LLM-Ausgabe ist nicht vertrauenswürdige Eingabe. Wenn Ihr Framework Teile dieser Ausgabe später als strukturierte Objekte behandelt, müssen Sie davon ausgehen, dass Angreifer versuchen, sie zu formen.
Aktualisieren Sie langchain-core auf die gepatchete Version. Wenn Sie langchain, langchain-community oder andere Ökosystem-Pakete verwenden, überprüfen Sie, welche Version von langchain-core tatsächlich in den Produktionsumgebungen installiert ist.
Behandeln Sie additional_kwargs, response_metadata, Tool-Ausgaben, extrahierte Dokumente und Nachrichtenverlauf als nicht vertrauenswürdig, sofern nicht das Gegenteil bewiesen ist. Dies ist besonders wichtig, wenn Sie Logs/Ereignisse streamen und später mit einem Loader rehydrieren.
Auch nach dem Update gilt das Prinzip: Aktivieren Sie keine Secret-Auflösung aus Umgebungsvariablen, es sei denn, Sie vertrauen der serialisierten Eingabe. Das Projekt hat die Standardeinstellungen aus gutem Grund geändert.
Basierend auf meinem Bericht gibt es eine eng verwandte Warnung in LangChainJS (GHSA-r399-636x-v7f6 / CVE-2025-68665) mit ähnlichen Mechanismen: 'lc'-Marker-Verwechslung während der Serialisierung, die die Extraktion von Geheimnissen und unsichere Instanziierung unter bestimmten Konfigurationen ermöglicht.
Wenn Ihre Organisation sowohl Python- als auch JavaScript-LangChain-Stacks betreibt, betrachten Sie dies als Erinnerung, dass das Muster zwischen Ökosystemen verbreitet ist: Marker-basierte Serialisierung, nicht vertrauenswürdige Modellausgabe und anschließende Deserialisierung sind eine wiederkehrende Risikoform.
Wir treten in eine Phase ein, in der KI-Agenten-Frameworks zu kritischer Infrastruktur in Produktionssystemen werden. Serialisierungsformate, Orchestrierungspipelines, Tool-Ausführung, Caching und Tracing sind nicht mehr „Sanitärtechnik“ – sie sind Teil Ihrer Sicherheitsgrenze.
Diese Schwachstelle ist nicht „nur ein Bug in einer Bibliothek.“ Sie ist eine Fallstudie für ein großes Muster:
Ihre Anwendung kann Daten deserialisieren, die sie für sicher produziert hält.
Aber diese serialisierte Ausgabe kann Felder enthalten, die von nicht vertrauenswürdigen Quellen beeinflusst werden (einschließlich LLM-Ausgaben, die durch Prompt-Injection geformt wurden).
Ein einziger reservierter Schlüssel, der als interner Marker verwendet wird, kann zum Drehpunkt für Geheimnisse und ausführungsnahes Verhalten werden.
Bei Cyata helfen wir Organisationen, Sichtbarkeit, Risikobewertung, Kontrolle und Governance rund um KI-Systeme aufzubauen – denn wenn Sie nicht schnell beantworten können, wo Agenten laufen, welche Versionen bereitgestellt sind und welche Daten durch sie fließen, fliegen Sie effektiv blind, wenn solche Warnungen wie diese eintreffen.
Wenn Sie ein Sicherheitsverantwortlicher sind, der dies liest, hier ist die unbequeme Wahrheit:
Die meisten Organisationen können derzeit nicht schnell und sicher beantworten:
Das ist kein „Entwicklerproblem.“ Es ist ein Sichtbarkeits- und Governance-Problem.
Und genau hier kommt Cyata ins Spiel.
Bei Cyata konzentrieren wir uns auf praktische Ergebnisse: Risikoreduzierung von KI und Agenten, ohne die Entwickler zu bremsen. Schwachstellen wie diese sind selten „einfach patchen.“ Sie offenbaren Lücken darin, wie Teams erkennen, wo Agenten laufen, die tatsächlichen Vertrauensgrenzen verstehen und sicherere Standardeinstellungen in schnelllebigen Frameworks gewährleisten.
Wissen, was läuft, wo und wie es angebunden ist.
Beantworten Sie schnell die erste CVE-Frage: Sind wir betroffen und in welchen Abläufen?
Entdecken Sie Agenten-Laufzeiten und Integrationen zwischen Umgebungen (IDEs, CI, Dienste, Job-Worker, Hosting-Agenten).
Verfolgen Sie Frameworks, Pakete und Versionen im Einsatz.
Priorisieren Sie, was basierend auf dem tatsächlichen Auswirkungsradius wichtig ist, nicht nur „Bibliothek vorhanden.“
Ermöglichen Sie schnellere Triage: Was ist internetexponiert, was betrifft Geheimnisse, was läuft mit erhöhten Privilegien?
Identifizieren Sie die Pfade mit dem höchsten Risiko: Nicht vertrauenswürdiger Inhalt, der in privilegierte Kontexte fließt (Dienste mit Geheimnissen, breite Tool-Berechtigungen, Netzwerkzugriff in der Produktion).
Heben Sie hervor, wo „strukturierte Felder“ Vertrauensgrenzen überschreiten können (Metadaten, Tool-Ausgaben, Streaming-Ereignisse, zwischengespeicherte Artefakte).
Reduzieren Sie die Exposition, noch bevor jede Abhängigkeit überall gepatched ist.
Fördern Sie sicherere operative Standardeinstellungen: geringste Privilegien, Isolationsgrenzen und Richtlinienprüfungen, die sich teamsübergreifend skalieren lassen.
Implementieren Sie Gateways um riskante Muster (z.B.: Deserialisierung nicht vertrauenswürdiger Daten, permissive Objekt-Wiederbelebung, unsichere Streaming-in-Cache-in-Rehydrierungsabläufe).
Gaten oder beschränken Sie sensible Fähigkeiten in nicht vertrauenswürdigen Kontexten (z.B.: Zugriff auf Geheimnisse aus der Umgebung, hochprivilegierte Tool-Ausführung oder Ausführung risikoreicher Codepfade in privilegierten Workern).
Machen Sie „sichere Agentennutzung“ wiederholbar, prüfbar und schwer abweichend.
Wenn die Weihnachtswarnung eintrifft, geht es nicht um Heldentum – es geht um eine ruhige, kontrollierte Antwort, gestützt auf ein echtes Inventar und abgesicherte Gateways.
Bericht über Huntr eingereicht – 4. Dezember 2025
Bestätigt durch LangChain-Maintainer – 5. Dezember 2025
Warnung und CVE veröffentlicht – 24. Dezember 2025