FlawOpen

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

● CWE-639 / CWE-863 · CVSS v4 8.6[1] · Высокий
Исследования · FlawOpen

LangGraph JS Auth: межпользовательский доступ к Store

Версии langgraph-api <0.15.0 могли терять namespace Store после JS/TS custom-auth, открывая доступ к чужим данным. Обновитесь до 0.15.0.[1], [2]

Вектор CVSSCVSS: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]
💡 Простыми словами (ELI5)

Представьте библиотеку: библиотекарь проверяет ваш читательский билет и просит другой стол выдать книгу. Тот стол записывает ваш стеллаж, но при передаче изменение теряется, и книга выдаётся со стеллажа, который изначально назвал посетитель. Уязвимый путь аутентификации JavaScript/TypeScript мог терять переписывание namespace между средой авторизации и операцией Store. Исправление передаёт разрешённый namespace и проверяет его до обращения к Store.[1]

Ключевые понятия и термины

GHSA-4hm6-w6qq-w73v
Уведомление LangGraph высокого уровня опубликовано 28 сентября 2026 года. CVE не присвоен. Затронут пакет langgraph-api; исправление выпущено в 0.15.0.[1]
Namespace Store
Иерархическое имя для группировки записей LangGraph Store. Приложения часто включают в него идентификатор пользователя или арендатора для разделения данных.[1]
Пользовательский обработчик авторизации
Код приложения, определяющий доступ аутентифицированного запроса к ресурсу и способный переписать namespace до операции Store.[1]
CWE-639 / CWE-863
Обход авторизации через контролируемый пользователем ключ и некорректная авторизация. Ограничение namespace, заданное обработчиком, не применялось.[1], [3], [4]

Связи со стандартами

  • Ссылка CWE для слабого места, описанного в этом руководстве: CWE-639 CWE-863

Пошаговый сценарий атаки

Шаг 1

Проверьте, соответствует ли развертывание условиям

Убедитесь, что используется langgraph-api >=0.1.2 и <0.15.0 и пользовательский обработчик аутентификации JavaScript или TypeScript.[1]

Шаг 2

Найдите переписывание namespace

Обработчик меняет запрошенный namespace, добавляя или проверяя идентификатор вошедшего пользователя, вместо отклонения запроса вне его namespace.[1]

Шаг 3

Результат авторизации пересекает границу runtime

В затронутых версиях изменение namespace может не попасть в операцию Store. Может использоваться исходный namespace, переданный запрашивающей стороной.[1]

Шаг 4

Аутентифицированный пользователь обращается к чужому namespace

Обычная учётная запись может запрашивать операции Store над записями вне собственного namespace. В уведомлении перечислены чтение, перезапись, поиск и удаление.[1]

Шаг 5

Обновите пакет или отклоняйте неразрешённые namespace

Обновите langgraph-api до >=0.15.0. Если это пока невозможно, отклоняйте неразрешённые namespace во всех операциях Store и проверяйте фактический namespace, получаемый Store.[1], [2]

Анализ первопричины

Уведомление GHSA от сопровождающих LangGraph, опубликованное 28 сентября 2026 года, описывает ошибку в langgraph-api версий >=0.1.2 и <0.15.0 при одновременном выполнении условий: развертывание использует пользовательскую аутентификацию JavaScript или TypeScript; обработчик авторизации Store переписывает запрошенный namespace, ограничивая данные текущим пользователем; обычный аутентифицированный пользователь может отправлять операции Store; данные разных пользователей проходят через этот путь авторизации. В уведомлении сказано, что пользовательские обработчики Python не затронуты. Обработчики JavaScript/TypeScript, отклоняющие неразрешённые namespace вместо их переписывания, также не затронуты. Изменение namespace обработчиком могло потеряться на границе runtime, поэтому операция Store использовала исходный namespace запроса. Аутентифицированный пользователь мог читать, перезаписывать, искать или удалять записи за пределами разрешённого namespace. Это не обход входа и не удалённая атака без аутентификации. Уведомление присваивает высокий уровень, CVSS 4.0 8,6, CWE-639 и CWE-863. Версия 0.15.0 передаёт изменения обработчика через границу, проверяет итоговый namespace и отклоняет некорректные или неприменённые изменения. До обновления сопровождающие рекомендуют отклонять неразрешённые namespace для каждой операции Store. Код ниже — сокращённая TypeScript-иллюстрация потока данных, а не исходный код SDK.[1]

Исходный код: Уязвимый vs Защищённый вариант

Этот сокращённый пример TypeScript иллюстрирует контракт границы; имена функций и форма результата условны и не являются исходным кодом SDK LangGraph. Уведомление подтверждает, что изменения авторизации JS/TS могли теряться до операции Store, но не публикует именно эту внутреннюю реализацию. Поэтому уязвимая сторона отражает только документированный инвариант: Store использует namespace запроса вместо разрешённого namespace. Исправленная сторона принимает и проверяет результат авторизации. Документированный временный вариант от сопровождающих — отклонять неразрешённые namespace во всех операциях Store, а не переписывать их.[1]

Фрагмент исходного кода: Граница авторизации LangGraph API и Store — сокращённый иллюстративный контракт

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
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.
}
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
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.
}

Чек-лист по защите системы для инженеров

Источники

← AI Security Directory →