FlawOpen

flawopen.com/AI Security/langgraph-js-custom-auth-cross-user-store-access

● CWE-639 / CWE-863 · CVSS v4 8.6[1] · Hoch
Sicherheitsforschung · FlawOpen

LangGraph JS Auth: mandantenübergreifender Store-Zugriff

langgraph-api <0.15.0 konnte Store-Namespaces aus JS/TS-Custom-Auth verlieren und so mandantenübergreifenden Zugriff ermöglichen. Update auf 0.15.0.[1], [2]

CVSS-VektorCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N[1]
💡 Einfache Erklärung (ELI5)

Stellen Sie sich eine Bibliothek vor: Der Bibliothekar prüft Ihren Ausweis und bittet einen zweiten Schalter, ein Buch zu holen. Der zweite Schalter trägt Ihr Regal ein, doch bei der Übergabe geht die Änderung verloren und er nutzt das Regal, das der Besucher ursprünglich genannt hat. Im betroffenen JavaScript/TypeScript-Auth-Pfad konnte die Namespace-Umschreibung zwischen Autorisierungs-Runtime und Store-Operation verloren gehen. Die Korrektur übergibt den autorisierten Namespace und prüft ihn, bevor der Store verwendet wird.[1]

Kernkonzepte & Begriffe

GHSA-4hm6-w6qq-w73v
Am 28. September 2026 veröffentlichte LangGraph eine Sicherheitsmeldung mit hohem Schweregrad. Eine CVE wurde nicht vergeben. Betroffen ist langgraph-api; korrigiert ab Version 0.15.0.[1]
Store-Namespace
Hierarchischer Name zur Gruppierung von LangGraph-Store-Datensätzen. Anwendungen verwenden häufig eine Nutzer- oder Tenant-ID darin, um Daten zu trennen.[1]
Benutzerdefinierter Autorisierungs-Handler
Anwendungscode, der über den Zugriff einer authentifizierten Anfrage entscheidet und den Namespace vor der Store-Operation umschreiben kann.[1]
CWE-639 / CWE-863
Autorisierungsumgehung über einen nutzerkontrollierten Schlüssel und fehlerhafte Autorisierung. Die Namespace-Beschränkung des Handlers wurde nicht angewendet.[1], [3], [4]

Framework-Zuordnungen

  • CWE-Referenz für die in diesem Leitfaden beschriebene Schwachstelle: CWE-639 CWE-863

Schritt-für-Schritt Angriffsablauf

Schritt 1

Prüfen, ob die Bereitstellung betroffen ist

Prüfen Sie langgraph-api >=0.1.2 und <0.15.0 sowie einen benutzerdefinierten JavaScript- oder TypeScript-Auth-Handler.[1]

Schritt 2

Namespace-Umschreibung finden

Der Handler ändert den angefragten Namespace, um die Identität des angemeldeten Nutzers einzubeziehen oder durchzusetzen, statt eine Anfrage außerhalb dieses Namespace zurückzuweisen.[1]

Schritt 3

Das Autorisierungsergebnis überschreitet eine Runtime-Grenze

In betroffenen Versionen wird die Namespace-Änderung möglicherweise nicht an die Store-Operation weitergegeben. Der ursprüngliche, vom Anfragenden gelieferte Namespace kann erhalten bleiben.[1]

Schritt 4

Ein angemeldeter Nutzer zielt auf einen fremden Namespace

Ein normales Konto kann Store-Operationen für Datensätze außerhalb des eigenen Namespace anfordern. Laut Advisory sind Lesen, Überschreiben, Suchen und Löschen möglich.[1]

Schritt 5

Aktualisieren oder unzulässige Namespaces zurückweisen

Aktualisieren Sie auf langgraph-api>=0.15.0. Bis dahin müssen alle Store-Aktionen unzulässige Namespaces zurückweisen; prüfen Sie, dass der Store nur den autorisierten Namespace erhält.[1], [2]

Ursachenanalyse

Das GHSA der LangGraph-Maintainer vom 28. September 2026 beschreibt einen Fehler in langgraph-api >=0.1.2 und <0.15.0, wenn alle folgenden Bedingungen erfüllt sind: Der Dienst verwendet benutzerdefinierte JavaScript- oder TypeScript-Authentifizierung; der Store-Autorisierungs-Handler schreibt den angefragten Namespace um, um Daten auf den aktuellen Nutzer zu begrenzen; ein normaler angemeldeter Nutzer kann Store-Operationen senden; und Daten mehrerer Nutzer laufen durch diesen Autorisierungspfad. Laut Advisory sind benutzerdefinierte Python-Handler nicht betroffen. JavaScript-/TypeScript-Handler, die unzulässige Namespaces zurückweisen, statt sie umzuschreiben, sind ebenfalls nicht betroffen. Die Namespace-Änderung des Handlers konnte an einer Runtime-Grenze verloren gehen, sodass die Store-Operation den ursprünglich angefragten Namespace verwendete. Ein angemeldeter Nutzer konnte dadurch Datensätze außerhalb seines autorisierten Namespace lesen, überschreiben, suchen oder löschen. Dies umgeht weder die Anmeldung noch ermöglicht es einen unauthentifizierten Fernangriff. Das Advisory bewertet den Fehler als Hoch, CVSS 4.0 8,6, mit CWE-639 und CWE-863. Version 0.15.0 überträgt die Änderungen des Handlers über die Grenze, prüft den resultierenden Namespace und weist fehlerhafte oder nicht anwendbare Änderungen zurück. Bis zum Upgrade empfiehlt der Maintainer, unzulässige Namespaces bei jeder Store-Aktion zurückzuweisen. Das Codepaar ist eine reduzierte TypeScript-Illustration des Datenflusses, nicht der SDK-Quellcode.[1]

Quellcode: Verwundbar vs. Sicher

Dieses reduzierte TypeScript-Beispiel veranschaulicht einen Grenzvertrag; Funktionsnamen und Ergebnisform sind beispielhaft und kein LangGraph-SDK-Quellcode. Das Advisory belegt, dass JS/TS-Autorisierungsänderungen vor der Store-Operation verloren gehen konnten, veröffentlicht aber nicht genau diese interne Implementierung. Die verwundbare Seite bildet daher nur die dokumentierte Invariante ab: Der Store nutzt den Anfrage-Namespace statt des autorisierten Namespace. Die korrigierte Seite übernimmt und validiert das Autorisierungsergebnis. Die dokumentierte Übergangslösung des Maintainers ist, unzulässige Namespaces für jede Store-Aktion zurückzuweisen, statt sie umzuschreiben.[1]

Quelltextauszug: Autorisierungsgrenze zwischen LangGraph API und Store — reduzierter Beispielvertrag

VERWUNDBARE IMPLEMENTIERUNG
type StoreRequest = { namespace: string[]; key: string };
type AuthorizationResult = { allowed: boolean; namespace: string[] };

async function readStore(userId: string, request: StoreRequest) {
  const authorization = await authorizeStore(userId, request); // Illustrative bridge contract.
  return store.get(request.namespace, request.key); // The bridge drops the authorized result.
}
GEHÄRTETER SICHERHEITS-PATCH
type StoreRequest = { namespace: string[]; key: string };
type AuthorizationResult = { allowed: boolean; namespace: string[] };

async function readStore(userId: string, request: StoreRequest) {
  const authorization = await authorizeStore(userId, request); // Illustrative bridge contract.
  if (!authorization.allowed) throw new Error("forbidden");
  const namespace = validateAuthorizedNamespace(userId, authorization.namespace);
  return store.get(namespace, request.key); // Apply the authorized result.
}

Checkliste für Engineering & Systemsicherheit

Quellen

← AI Security Directory →