flawopen.com/Teardowns/cve-2026-71433-langgraph-store-namespace-boundary
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 CVSS
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:NBayangkan 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:
foomencakupfoo.child, tetapi bukan namespace tetanggafoobar. 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 namespace | Perilaku yang didokumentasikan | Tindakan 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
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.
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.
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.
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.
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
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
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
- ✓Perbarui
langgraph-checkpoint-postgresdanlanggraph-checkpoint-sqliteke 3.1.1 atau lebih baru di semua instalasi. - ✓Tambahkan regresi dengan label tenant yang satu menjadi prefix label lain, misalnya
foodanfoobar, lalu pastikan pencarian hanya mengembalikan namespace yang diminta beserta turunannya. - ✓Uji label berisi
%,_, backslash, dan perbedaan huruf besar/kecil saja menggunakan backend database produksi yang sama. - ✓Uji prefix, suffix, wildcard, dan jalur kosong pada
list_namespaces; pastikan*cocok dengan tepat satu segmen sesuai dokumentasi. - ✓Pertahankan pemeriksaan otorisasi pada batas aplikasi; ID namespace yang opaque atau berformat tetap tidak menggantikan verifikasi kepemilikan tenant.