
Co znajdziesz w tym artykule?
- 1 Wprowadzenie do problemu / definicja luki
- 2 W skrócie
- 3 Kontekst / historia / powiązania
- 4 Analiza techniczna / szczegóły luki
- 5 Praktyczne konsekwencje / ryzyko
- 6 Rekomendacje operacyjne / co zrobić teraz
- 7 Różnice / porównania z innymi przypadkami
- 8 Podsumowanie / kluczowe wnioski
- 9 Źródła / bibliografia
Wprowadzenie do problemu / definicja luki
Pod koniec grudnia 2025 ujawniono krytyczną podatność w langchain-core (Python) – podstawowej bibliotece ekosystemu LangChain – która pozwala atakującemu „przemycić” spreparowaną strukturę danych do procesu serializacji/deserializacji i w efekcie wyciągać sekrety (np. zmienne środowiskowe) oraz inicjować niebezpieczne ścieżki wykonania w ramach obiektów frameworka. Luka otrzymała identyfikator CVE-2025-68664 i przydomek LangGrinch.
Równolegle opisano podobny problem w implementacji LangChain.js (CVE-2025-68665), dotyczący sposobu serializacji w JavaScript/TypeScript.
W skrócie
- CVE-2025-68664 (Python / langchain-core): podatność typu serialization injection w
dumps()/dumpd(), oceniona jako krytyczna (CVSS 9.3). - Mechanizm nadużycia opiera się o wewnętrzny znacznik
"lc", który LangChain traktuje jako sygnał, że dane reprezentują „prawdziwy” obiekt frameworka, a nie zwykły słownik. - Najczęstszy wektor: pola odpowiedzi LLM (np.
additional_kwargs,response_metadata) sterowane pośrednio przez prompt injection, a następnie serializowane i deserializowane w przepływach strumieniowych. - Poprawki: aktualizacja do langchain-core 0.3.81 lub 1.2.5 (w zależności od gałęzi).
- Dodatkowo: analogiczna luka w LangChain.js (CVE-2025-68665, CVSS 8.6) – poprawione m.in. w @langchain/core 0.3.80 / 1.1.8 i langchain 0.3.37 / 1.2.3.
Kontekst / historia / powiązania
LangChain i langchain-core stały się fundamentem wielu wdrożeń „agentowych” (orchestracja narzędzi, pamięć, streaming, logowanie zdarzeń). Problem LangGrinch jest groźny nie dlatego, że dotyczy rzadkiego modułu, ale dlatego, że dotyka mechanizmu wymiany/utrwalania danych (serializacja), który bywa używany „w tle” w popularnych API i integracjach.
W praktyce to kolejny przykład klasycznej kategorii błędów (deserializacja danych niezaufanych), ale w nowym kontekście: LLM output jako dane wejściowe. Wiele zespołów nadal traktuje odpowiedź modelu jak „bezpieczny tekst”, podczas gdy jest to treść, którą przeciwnik może kształtować promptami, danymi w RAG, a czasem nawet treścią zewnętrznych źródeł.
Analiza techniczna / szczegóły luki
Na czym polega „serialization injection” w LangChain?
W LangChain istnieje wewnętrzny format, który opisuje obiekty frameworka jako struktury danych. Klucz lc jest częścią tego mechanizmu: sygnalizuje, że dana struktura ma być traktowana jak serializowany obiekt LangChain.
W CVE-2025-68664 problem polegał na tym, że funkcje dumps() i dumpd() nie „uciekały” (nie neutralizowały) słowników zawierających lc w dowolnych, swobodnych danych. Gdy taki wynik został później przepuszczony przez load()/loads(), wstrzyknięta struktura mogła zostać zinterpretowana jako legalny obiekt LangChain, a nie zwykłe dane użytkownika.
Co realnie umożliwia atak?
Z advisory wynika kilka praktycznych wektorów:
- Ekstrakcja sekretów z env – historycznie ryzykowny wariant, bo wcześniejsze domyślne ustawienia pozwalały automatycznie pobierać sekrety ze zmiennych środowiskowych podczas deserializacji (
secrets_from_envbyło domyślnie włączone). - Instancjonowanie klas w „zaufanych” przestrzeniach nazw (
langchain_core,langchain,langchain_community) – nawet jeśli to nie jest „dowolna klasa z systemu”, nadal mogą istnieć konstruktory z efektami ubocznymi (połączenia sieciowe, operacje na plikach, itp.). - Powiązanie z prompt injection – ponieważ pola typu
additional_kwargs/response_metadatamogą zostać ukształtowane przez atakującego (np. przez wymuszenie specyficznego JSON-a w odpowiedzi), a potem trafić do serializacji w strumieniowaniu.
Cyata opisuje też scenariusze, w których instancjonowane obiekty mogą powodować wyjściowe żądania sieciowe albo prowadzić do dalszych eskalacji, jeśli aplikacja po deserializacji wykona kolejne kroki „ufając” obiektom.
Co zmieniły poprawki (i dlaczego mogą „boleć”)?
W przypadku Pythona łatka nie tylko naprawia błąd escapowania, ale też wprowadza utwardzenie bezpieczeństwa:
- domyślna allowlista (
allowed_objects="core"), secrets_from_envdomyślnie False,- blokada szablonów Jinja2 przez
init_validator(zmiana potencjalnie „breaking” dla części użytkowników).
Praktyczne konsekwencje / ryzyko
Największe ryzyka dla zespołów budujących aplikacje i agentów LLM:
- Wyciek kluczy API (LLM provider, narzędzia, bazy wektorowe, systemy zewnętrzne), jeśli środowisko wykonawcze ma sekrety w zmiennych środowiskowych, a ścieżka deserializacji została osiągnięta.
- Nieoczekiwane zachowanie agenta – atakujący może „dosztukować” struktury, które zmienią sposób działania łańcucha, logowania, pamięci, narzędzi lub dalszego generowania odpowiedzi (w praktyce: prompt injection + nadużycie serializacji).
- Efekty uboczne w zaufanych klasach – nawet bez pełnego RCE, sam fakt inicjowania ruchu wychodzącego, odczytów plików czy nietypowych operacji może być bolesny (SSRF, exfil, kosztowe DoS).
Rekomendacje operacyjne / co zrobić teraz
- Zaktualizuj zależności natychmiast
- Python: przejdź na langchain-core 0.3.81 albo 1.2.5 (zależnie od używanej linii).
- JS: @langchain/core 0.3.80 / 1.1.8 oraz langchain 0.3.37 / 1.2.3.
- Załóż, że output LLM to dane niezaufane
- Traktuj
additional_kwargs,response_metadata,metadatajak payload z internetu. - Jeśli logujesz/serializujesz odpowiedzi modelu – wprowadź walidację i/lub filtrację (np. blokada klucza
lcw danych swobodnych).
- Traktuj
- Usuń automatyczne ładowanie sekretów z env przy deserializacji
- Po łatkach domyślnie jest bezpieczniej, ale warto audytować kod: czy gdziekolwiek jawnie włączasz
secrets_from_env/secretsFromEnv.
- Po łatkach domyślnie jest bezpieczniej, ale warto audytować kod: czy gdziekolwiek jawnie włączasz
- Ogranicz deserializację do minimum
- Jeśli musisz używać
load()/loads(): trzymaj się allowlisty i nie deserializuj niczego, co może pochodzić od użytkownika/LLM/RAG/cache/hub bez walidacji.
- Jeśli musisz używać
- Sprawdź „wrażliwe” ścieżki z advisory
- Python: szczególnie przypadki użycia streamingu i narzędzi, które wewnętrznie serializują zdarzenia (np.
astream_eventsw wersji v1,Runnable.astream_log()i inne wskazane w advisory).
- Python: szczególnie przypadki użycia streamingu i narzędzi, które wewnętrznie serializują zdarzenia (np.
- Dodaj kontrolę w pipeline
- SCA/Dependabot + blokada wdrożeń z podatnymi wersjami.
- SBOM i alertowanie przy wykryciu
langchain-corew podatnym zakresie.
Różnice / porównania z innymi przypadkami
- Python (CVE-2025-68664): podatność w
dumps()/dumpd()+ twarde zmiany bezpieczeństwa wload()/loads()(allowlista, wyłączenie sekretów z env, blokada Jinja2). - JavaScript (CVE-2025-68665): podatność w
Serializable.toJSON()/JSON.stringify()+ deserializacja przezload(); hardening obejmuje m.in. jawne wyłączeniesecretsFromEnvoraz limit głębokości (maxDepth) przeciw DoS.
W obu światach wspólny mianownik jest ten sam: framework myli dane użytkownika z danymi strukturalnymi (bo klucz lc ma specjalne znaczenie), a to tworzy „most” między prompt injection a klasycznymi kategoriami błędów bezpieczeństwa.
Podsumowanie / kluczowe wnioski
LangGrinch (CVE-2025-68664) to sygnał ostrzegawczy dla zespołów budujących agentów i aplikacje LLM: jeśli jakikolwiek fragment odpowiedzi modelu trafia do serializacji/deserializacji, to w praktyce traktujesz LLM jak niezaufanego nadawcę danych. Najważniejsze działania to szybka aktualizacja do wersji naprawionych, ograniczenie deserializacji, wyłączenie automatycznego ładowania sekretów z env i wprowadzenie allowlist / walidacji struktur.
Źródła / bibliografia
- The Hacker News – opis CVE-2025-68664 i CVE-2025-68665 oraz podatne/naprawione wersje (The Hacker News)
- GitHub Advisory (langchain-core, CVE-2025-68664 / GHSA-c67j-w6g6-q2cm) – wektory ataku, wpływ, zmiany hardening (GitHub)
- GitHub Advisory (LangChain.js, CVE-2025-68665 / GHSA-r399-636x-v7f6) – zakres npm, hardening
load()(GitHub) - Cyata Research – kontekst „LangGrinch”, scenariusze ryzyka w agentach (Cyata)