
Nuclei-шаблон для обнаружения CVE-2026-33017 — уязвимости удалённого выполнения кода без аутентификации в Langflow ≤ 1.8.2. Выполняет неразрушающие предварительные проверки, чтобы отличить уязвимые сборки от пропатченных с помощью анализа HTTP-ответов.
Шаблон Nuclei для обнаружения CVE-2026-33017 — неаутентифицированной уязвимости удалённого выполнения кода в Langflow ≤ 1.8.2, доступной через публичную конечную точку сборки flow:
POST /api/v1/build_public_tmp/{flow_id}/flow
Уязвимый обработчик принимает управляемый атакующим граф потока data и передаёт data.nodes[].data.node.template.code.value напрямую в Python exec() во время сборки графа без песочницы. Исправление (≥ 1.9.0) убирает параметр data из сигнатуры обработчика, поэтому исправленная сборка отклоняет тот же запрос на уровне валидации FastAPI с HTTP 422.
Шаблон является неразрушающим. Он отправляет инертный полезный нагрузочный запрос (payload) на нулевой UUID flow ID, поэтому он не может достичь exec() даже на уязвимом хосте. Он отличает уязвимый обработчик от исправленного только по сигнатуре HTTP-ответа.
| Stage | Request | What it tells you |
|---|---|---|
| 1 | GET /api/v1/version | Подтверждает, что цель — Langflow, и извлекает версию сборки. |
Маршрутизация для этапа 2:
Подтверждение реального RCE по-прежнему требует (a) реального PUBLIC flow UUID на целевой системе и (b) внеполосного колбэка (DNS/HTTP). Этот шаг намеренно не включён сюда — данный шаблон является безопасной предварительной проверкой, которая определяет, имеет ли смысл запускать активный эксплойт.
Одиночный хост:
nuclei -t CVE-2026-33017.yaml -u https://target.example.com
Массовое сканирование из списка:
nuclei -t CVE-2026-33017.yaml -l targets.txt -rl 20 -c 10
С выводом отладочной информации (см. исходные запросы/ответы):
nuclei -t CVE-2026-33017.yaml -u https://target.example.com -debug-req -debug-resp
Проверьте шаблон локально перед запуском:
nuclei -validate -t CVE-2026-33017.yaml
Уязвимая цель:
[CVE-2026-33017] [http] [critical] https://target.example.com [vulnerable-flow-not-found] ["1.8.2","base"]
Исправленная цель — находок нет (ответ 422 не соответствует ни одному правилу).
Типичные поисковые запросы для обнаружения хостов Langflow (используйте только против активов, которые вам разрешено тестировать):
http.title:"Langflow"app="Langflow"intitle:"Langflow" inurl:"/flows"AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HВ уязвимых сборках публичный обработчик объявляется примерно так:
@router.post("/build_public_tmp/{flow_id}/flow")
async def build_public_flow(flow_id: UUID, data: FlowDataRequest | None = None, ...):
...
await verify_public_flow_and_get_user(flow_id, ...)
...
# data.nodes[].data.node.template.code.value reaches exec() in the
# Component build path
data контролируется атакующим. Исправленный обработчик полностью удаляет этот параметр и принудительно устанавливает data=None, поэтому запрос, включающий поле data в теле, отклоняется с 422 на исправленных сборках.
/api/v1/build_public_tmp/ на обратном прокси.LANGFLOW_AUTO_LOGIN=False, настройте учётные данные суперпользователя и смените LANGFLOW_SECRET_KEY.access_type=PUBLIC станут целью атакующего в URL.Этот шаблон опубликован только для защитного обеспечения безопасности и авторизованного тестирования. Запуск его против систем, которыми вы не владеете или на тестирование которых у вас нет явного письменного разрешения, является незаконным в большинстве юрисдикций и нарушает условия использования платформ.
Используя этот шаблон, вы соглашаетесь с тем, что:
lopseg — https://github.com/lopseg
Пул-реквесты и issues приветствуются.
MIT
| 2 | POST /api/v1/build_public_tmp/00000000-0000-0000-0000-000000000000/flow с телом, содержащим поле data и инертное значение template.code.value | Решение о маршрутизации ниже. |
| Status | Body contains | Verdict |
|---|
404 | flow / public | УЯЗВИМО — обработчик принял data, затем поиск не удался, потому что UUID поддельный. |
200 | job_id / build / task | УЯЗВИМО — обработчик принял data и вошёл в путь сборки. |
5xx | exec / Component / traceback | УЯЗВИМО — обработчик достиг кода exec до сбоя. |
422 | Field required / extra / data | ИСПРАВЛЕНО — сигнатура обработчика больше не принимает data. |