Přeskočit na obsah
Bezpečnost aktualizováno 10. 8. 2026 4 min čtení

Úložiště LangGraphu vracelo i záznamy z prostoru, jehož jméno začínalo stejně

Knihovna LangGraph ukládá paměť agentů do jmenných prostorů a aplikace jimi běžně oddělují data jednoho uživatele od druhého. Úložiště pro Postgres a SQLite je ale porovnávala operátorem LIKE, který nezná tečkový oddělovač, takže dotaz omezený na jeden prostor vracel i záznamy ze sousedního. Oprava vyšla 30. července 2026, popis chyby o týden později.

Dřevěná kartotéka se zásuvkami plnými lístků
Jmenný prostor je v úložišti LangGraphu totéž co zásuvka v kartotéce: má oddělit lístky jednoho uživatele od lístků druhého. Foto: Bibliothek Wissenschaftspark Albert Einstein, Wikimedia Commons (CC BY-SA 4.0)

LangGraph je knihovna, ve které se staví agenti nad jazykovými modely: popíše se graf kroků a knihovna se stará o jejich pořadí a o paměť mezi nimi. Tu paměť drží takzvaný store, tedy úložiště, a pro ostrý provoz k němu vývojáři berou balíčky langgraph-checkpoint-postgres nebo langgraph-checkpoint-sqlite. Právě v nich byla chyba, kterou projekt popsal 6. srpna 2026 pod označením CVE-2026-71433.

Záznamy se v úložišti třídí do jmenných prostorů, což je uspořádaná dvojice, trojice či delší řada popisků: ("memories", "alice"). Do databáze se ale ukládá jako jediný řetězec spojený tečkami, tedy memories.alice, a čtení omezené na jeden prostor se dělalo porovnáním LIKE se začátkem toho řetězce. Operátor LIKE ale o tečce nic neví. Dotaz omezený na ("foo",) proto vracel i záznamy z ("foobar",) a z ("foo2",).

Kdy se z toho stane únik dat

Samo o sobě je to chyba v dotazu. Váhu jí dává to, k čemu se jmenné prostory běžně používají: aplikace jimi oddělují data jednoho uživatele nebo zákazníka od druhého. Kde je hranicí jmenný prostor, tam mohl obyčejný dotaz vrátit cizí záznamy. Nic vyrobeného na míru k tomu podle hlášení potřeba nebylo, stačil běžný požadavek.

Hlášení popisuje tři podoby téhož omylu:

  • Sousední prostory. Čtení omezené na ("foo",) vrátilo i položky z ("foobar",) a ("foo2",).
  • Neošetřené zástupné znaky. Znaky _ a % jsou v popisku prostoru povolené (zakázaná je jen tečka), jenže do porovnávacího vzoru se dosazovaly tak, jak jsou. V jazyce SQL přitom zastupují jeden libovolný znak a libovolný počet znaků, takže ("user_1",) sedělo i na ("userX1",).
  • Shoda na konci. Dotaz list_namespaces(suffix=("alice",)) sedl i na sousední users.malice.

Vkládání cizího SQL to není a projekt na tom trvá: hodnoty se předávaly jako vázané parametry a do textu dotazu se nikdy nevkládaly. Vzorem pro LIKE byla sama ta hodnota, jen s neošetřenými zástupnými znaky. Proti třem starším dírám v témže úložišti je to podstatný rozdíl: CVE-2025-67644, CVE-2025-64104 i CVE-2025-8709 z podzimu a zimy 2025 byly vkládání SQL přes klíč filtru a všechny tři měly závažnost vysokou.

Koho se to netýká

Zasažená je aplikace, která splní tři podmínky najednou: používá PostgresStore nebo SqliteStore (i v asynchronní podobě), spoléhá na jmenný prostor jako na hranici mezi uživateli a má popisky, kde jeden může být začátkem druhého (1 a 12, alice a alice2) nebo obsahuje _ či %. Kdo prostory pojmenovává identifikátory pevné délky, typicky UUID, zasažený není: žádný takový popisek nemůže být začátkem jiného. InMemoryStore porovnává prostory po prvcích a chybu nikdy neměl.

Nedotčené zůstaly i operace get, put a delete, protože ty prostory porovnávají přes rovnítko. Vada byla jen na straně čtení a odpovídá tomu i hodnocení závažnosti: 5,3 bodu z deseti, důvěrnost vysoká, celistvost i dostupnost nulové. To číslo pochází od GitHubu a americká databáze NVD ho přebírá jako druhotné, vlastní hodnocení k němu nepřipojila.

Oprava mění chování hvězdičky

Ve verzi 3.1.1 obou balíčků musí prostor sedět buď přesně, nebo za shodným začátkem musí následovat tečka. Zástupné znaky v popiscích se ošetřují a list_namespaces porovnává po segmentech. V Postgresu k tomu slouží regulární výraz místo LIKE, v SQLite se sestupné hledání přesunulo na GLOB.

Ten přesun srovnal ještě jednu nesrovnalost. LIKE v SQLite nerozlišuje u znaků ASCII velikost písmen, takže hledání dosud našlo i prostory lišící se jen velkým a malým písmenem, zatímco zápisové operace je považovaly za dva různé. Teď se shodnou.

Povýšení ale není zadarmo. Hvězdička v cestě u list_namespaces nově zabírá přesně jeden segment, ne libovolný počet. Projekt to označuje za návrat k dokumentovanému chování, protože ("cache", "*", "v1") je podle dokumentace libovolná kategorie mezipaměti s verzí v1; víceúrovňová shoda byla vedlejším produktem téhož mechanismu, který chybu způsobil, a zachovat ji prý při opravě nešlo. Kdo potřebuje shodu v libovolné hloubce, má podle projektu zkombinovat obě podmínky, prefix i suffix; platí zároveň.

Co je vidět z čísel opravy

Změna prošla jako návrh 8478, sloučený 30. července 2026, a dotkla se šesti souborů. Přidala 554 řádků a ubrala 36. Z přidaných řádků je 379 v testech a 175 ve vlastním kódu; obojí je náš součet z čísel, která u jednotlivých souborů uvádí rozhraní GitHubu. Na jeden řádek opravy tak vyšly zhruba dva řádky testu.

Opravné verze obou balíčků vyšly 30. července 2026, popis chyby o týden později. Tentýž odstup mezi opravnou verzí a zveřejněným hlášením jsme popisovali u Open WebUI, kde šlo o osm dní.

Co s tím

Kdo LangGraph provozuje nad Postgresem nebo SQLite, má povýšit na 3.1.1 a projít si, jestli jeho popisky jmenných prostorů můžou být začátkem jiných. Projekt sám radí dvě věci: dávat prostorům identifikátory pevné délky, aby žádný nemohl být začátkem jiného, a popisky pocházející od uživatele ověřovat na vstupu, místo aby se spoléhalo jen na omezení dotazu.

Zvláštní odstavec věnuje hlášení hostovaným nasazením. Na rozdíl od dřívějších hlášení o tomhle úložišti se tohle týká i jich: nasazení LangSmith mají ve výchozím stavu nastavené LANGGRAPH_STORE_BACKEND=python, což je právě AsyncPostgresStore z opravovaného balíčku. Varianta grpc je jiná implementace a dostala odpovídající opravu zvlášť. Že by chybu někdo zneužil, projekt nezaznamenal a píše to v hlášení výslovně.

Zdroje: hlášení GHSA-47pj-3jcm-6whg projektu LangGraph, záznam CVE-2026-71433 v databázi NVD amerického úřadu NIST, návrh 8478 a poznámky k vydání obou opravených balíčků.

Diskuse

Zatím tu nikdo nediskutuje. Můžete být první.

Napsat příspěvek

Diskutovat můžete i bez účtu. S registrací se ale příspěvek zveřejní hned a nemusíte pokaždé vyplňovat jméno. Účet už máte? Přihlaste se.

Nezveřejňujeme ho, slouží jen redakci.

Podporuje zápis Texy: **tučně**, *kurzíva*, odrážky, odkazy.

Dál k tématu

  1. Bezpečnost

    Doloženou opravu chyby Plugin4Shell mají ze čtyř agentů jen Claude Code a Codex

    Firma Air Security v září popsala, jak u Claude Code, Codexu, GitHub Copilotu a Gemini CLI podvrhnout plugin, který tržiště připnulo na prověřený commit. Anthropic chybu…

  2. Bezpečnost

    Agenti z Tencent Cloud se hlásili jako Claude, styl jejich kódu ale Claudovi neodpovídá

    Agenti AI běžící na Tencent Cloud se mezi 28. zářím a 8. říjnem 2026 přes 2 600krát pokusili stáhnout data z mapové služby Amap, obcházeli její ochranu proti robotům a…

  3. Bezpečnost

    Compliance API Clauda vrací firemní správě i osobní pokyny zaměstnanců

    Rozhraní Compliance API vrací od 15. října text, který si každý člen firemní organizace uložil jako svůj vlastní pokyn pro Clauda. Koncový bod je v betě a spadá pod…

  4. Bezpečnost

    Grok v simulaci poslal 187 zpráv kvůli vrácení jízdného po lhůtě

    Šest AI asistentů mělo získat 350 liber za zrušený vlak, přestože zákaznice zmeškala lhůtu k žádosti. Grok v simulaci poslal 187 zpráv a Claude Fable sdílel soukromou…