FlawOpen

flawopen.com/Teardowns/cve-2026-71433-langgraph-store-namespace-boundary

● CVE-2026-71433 · CVSS 5.3 · Sedang
Riset Keamanan · FlawOpen

LangGraph CVE-2026-71433: batas namespace bocor

Pembacaan berscope di Postgres dan SQLite LangGraph dapat melintasi batas namespace dan membuka data tenant tetangga. Perbarui kedua paket checkpoint ke 3.1.1.

Vektor CVSSCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N
💡 Penjelasan Sederhana (ELI5)

Bayangkan pustakawan diminta mencari folder yang namanya diawali “tim”. Jika katalog hanya memeriksa teks awal, folder “tim2” juga bisa muncul. LangGraph menggabungkan label namespace dengan titik, tetapi pencarian prefix tidak mewajibkan titik itu sebagai batas. Perbaikannya mensyaratkan namespace yang persis atau segmen berikutnya yang nyata, sehingga folder milik tenant lain tidak tercampur.

Konsep Kunci & Istilah

Namespace
Tuple label yang dipakai LangGraph Store untuk mengelompokkan item. Aplikasi dapat menjadikannya batas antar pengguna atau tenant.
Cakupan prefix
Permintaan untuk membaca satu namespace dan turunannya. Pencocokan yang benar mengikuti batas segmen: foo mencakup foo.child, tetapi bukan namespace tetangga foobar.
Pola SQL `LIKE`
Pola teks dengan % untuk urutan karakter apa pun dan _ untuk satu karakter. Karakter ini perlu di-escape bila label namespace harus dianggap literal.
CWE-863
Otorisasi tidak benar: Store mengembalikan rekaman di luar namespace yang boleh dibaca pemanggil.

Pemetaan kerangka kerja

  • Referensi CWE untuk kelemahan yang dijelaskan dalam panduan ini: CWE-863

Analisis Akar Masalah (Root Cause)

Sebelum 3.1.1, checkpoint store Postgres dan SQLite meratakan tuple namespace dengan titik lalu membatasi pencarian memakai LIKE '<namespace>%'. LIKE tidak memahami pemisah namespace, sehingga pencarian foo juga dapat cocok dengan namespace tetangga foobar; label % dan _ yang sah juga dapat berfungsi sebagai wildcard. list_namespaces memiliki kesalahan serupa pada pencocokan prefix dan suffix. Pembacaan berscope biasa sudah cukup; input cacat tidak diperlukan. Masalah ini hanya memengaruhi jalur baca search dan daftar namespace pada Store Postgres/SQLite ketika aplikasi mengandalkan namespace untuk pemisahan tenant. get, put, dan delete memakai kesetaraan persis dan tidak terdampak; InMemoryStore membandingkan elemen namespace satu per satu dan juga tidak terdampak. Perbaikan mensyaratkan kesetaraan persis atau titik sebelum segmen turunan, meng-escape metakarakter LIKE, dan memakai pola sadar-segmen untuk daftar namespace. Di SQLite, pencarian juga menghindari perilaku LIKE yang tidak membedakan huruf ASCII besar/kecil. Advisory menyatakan tidak ada bukti eksploitasi di dunia nyata. Paket terdampak diperbaiki di 3.1.1.

Matriks jangkauan CVE-2026-71433 menurut deployment

Deployment dan bentuk namespacePerilaku yang didokumentasikanTindakan triase
PostgresStore / AsyncPostgresStore atau SqliteStore / AsyncSqliteStore sebelum 3.1.1; pemisahan tenant bergantung pada namespace.Pencarian search atau list_namespaces dengan cakupan dapat menjangkau namespace tetangga jika label berbagi prefiks teks (foo / foobar, 1 / 12) atau berisi % / _. Pencarian SQLite juga menyamakan perbedaan huruf ASCII saja.Perbarui paket checkpoint yang relevan ke 3.1.1 atau lebih baru. Uji prefiks tetangga, karakter wildcard, akhiran, dan perbedaan kapitalisasi pada backend produksi.
SQLite Store sebelum 3.1.1 dengan label namespace yang hanya berbeda kapitalisasi ASCII.Pencarian descendant yang rentan memakai LIKE yang tidak membedakan kapitalisasi, sedangkan operasi exact membedakannya.Perbarui dan tambahkan uji regresi kapitalisasi jika label dapat berbeda seperti itu.
Label UUID panjang tetap tanpa % atau _.Advisory menyatakan skema ini tidak terdampak: label dengan panjang tetap tidak dapat menjadi prefiks satu sama lain.Pastikan setiap segmen namespace memenuhi invarian ini. Jika label dapat bervariasi atau berisi wildcard, anggap deployment terdampak.
InMemoryStore.Tidak terdampak: elemen namespace dibandingkan satu per satu.Tidak perlu peningkatan untuk CVE ini; tetap periksa kepemilikan tenant di batas aplikasi.
Deployment LangSmith yang di-host.Default LANGGRAPH_STORE_BACKEND=python memakai AsyncPostgresStore dan termasuk cakupan jika paket yang terdampak digunakan. Backend grpc terpisah menerima perbaikan setara.Periksa backend yang dikonfigurasi dan versi yang benar-benar berjalan; verifikasi rollout hosting atau versi paket, jangan menyimpulkan dari nama produk saja.

Alur Serangan Langkah demi Langkah

Langkah 1

Periksa backend Store dan label

Deployment harus memakai langgraph-checkpoint-postgres atau langgraph-checkpoint-sqlite sebelum 3.1.1 dan mengandalkan namespace untuk memisahkan pengguna atau tenant. Prefix yang bertumpang tindih atau label % dan _ membuat batas ini relevan.

Langkah 2

Pembacaan berscope biasa dilakukan

Permintaan aplikasi yang sudah terautentikasi mencari namespace seperti foo. Tidak perlu payload khusus; namespace biasa menjadi masukan bagi pencocok yang rentan.

Langkah 3

Backend meratakan label lalu mencocokkan pola

Store menggabungkan label dengan titik dan memakai prefix LIKE yang diakhiri %. Karena pemisah tidak diwajibkan, foo dapat cocok dengan foobar; karakter pola pada label juga dapat memperluas hasil.

Langkah 4

Item namespace tetangga dapat ikut dikembalikan

Jika aplikasi memperlakukan namespace sebagai batas tenant, pencarian atau daftar dapat mengembalikan item milik pengguna lain. Ini masalah kerahasiaan pada jalur baca, bukan SQL injection atau akses tulis.

Langkah 5

Perbarui dan uji ulang isolasi

Perbarui kedua paket yang berlaku ke 3.1.1 atau lebih baru. Uji prefix tetangga, label literal % dan _, suffix, serta perilaku huruf besar/kecil SQLite dengan tenant uji yang terpisah.

Kode Sumber: Rentan vs Aman

Predikat rentan menganggap semua string yang diawali namespace hasil perataan sebagai turunan. Perbaikan menambahkan kondisi kesetaraan persis dan mewajibkan titik literal sebelum segmen turunan; pola LIKE juga meng-escape backslash, %, dan _. Commit upstream turut mengganti pola prefix/suffix list_namespaces dengan pencocokan sadar-segmen dan menyesuaikan pencarian SQLite. Ini cuplikan sumber, bukan pengganti modul lengkap.

Cuplikan sumber: libs/checkpoint-postgres/langgraph/store/postgres/base.py

IMPLEMENTASI RENTAN
def _prepare_batch_search_queries(op):
    ns_condition = "TRUE"
    ns_param = None
    if op.namespace_prefix:
        ns_condition = "store.prefix LIKE %s"
        ns_param = (f"{_namespace_to_text(op.namespace_prefix)}%",)
    return ns_condition, ns_param
PERBAIKAN AMAN & KUAT
def _escape_like_literal(text: str) -> str:
    return text.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")

def _namespace_prefix_condition(namespace_prefix: tuple[str, ...]) -> tuple[str, tuple]:
    path = _namespace_to_text(namespace_prefix)
    condition = r"(store.prefix = %s OR store.prefix LIKE %s ESCAPE '\\')"
    return condition, (path, f"{_escape_like_literal(path)}.%")

if op.namespace_prefix:
    ns_condition, ns_param = _namespace_prefix_condition(op.namespace_prefix)

Daftar Periksa Penguatan Sistem Rekayasa

Sumber