Přeskočit na obsah
Bezpečnost 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",)("foo2",).
  • Neošetřené zástupné znaky. Znaky _% 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-64104CVE-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 (112, alicealice2) 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, putdelete, 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, prefixsuffix; 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

    Open WebUI vydalo sedmnáct záznamů CVE až osm dní po opravné verzi

    Rozhraní Open WebUI, které si lidé staví před vlastní modely, vydalo 27. července 2026 verzi 0.11.0 s bezpečnostními opravami a v poznámkách rovnou napsalo, že je zatím…

  2. Bezpečnost

    Codex a Claude Code zpřísnily ochranu tokenů a pravidla sandboxu

    Codex 0.147 začal v zobrazených příkazech a obnovené historii skrývat celé bearer tokeny. Claude Code 2.1.224 opravil obcházení zákazu čtení cestou s koncovým lomítkem a…

  3. Bezpečnost

    GitHub Copilot a Visual Studio Code dostaly najednou šest bezpečnostních záplat

    Microsoft zveřejnil 14. července 2026 během jednoho dne šest záznamů CVE pro dvojici GitHub Copilot a Visual Studio Code – pět pro samotný editor, jeden pro plugin…

  4. Bezpečnost

    Dva ze čtyř záznamů u MCP serveru Dynatrace míří na ochrany, které nic nevynutí

    Balíček @dynatrace-oss/dynatrace-mcp-server dostal mezi 29. a 31. červencem čtyři bezpečnostní záznamy. Nejvyšší číslo má režim HTTP, který se nikoho neptá na heslo. Dva…