FlawOpen

flawopen.com/Teardowns/cve-2026-105697-langflow-mcp-stdio-command-injection

● CVE-2026-105697 · CVSS 9.9[1] · 심각
보안 연구 · FlawOpen

CVE-2026-105697: Langflow MCP 명령 주입

Langflow 1.10.3 이전 버전은 MCP stdio 설정을 셸로 시작하는 프로세스에 전달했습니다. 네트워크에 노출된 인스턴스에서 개발용 기본값인 LANGFLOW_AUTO_LOGIN=true가 켜져 있으면 공격자는 자격 증명 없이 토큰을 얻을 수 있었습니다. 자동 로그인을 꺼도 인증된 비관리자 사용자가 호스트에서 명령을 실행할 수 있었습니다. 1.10.3은 모든 진입점과 프로세스 실행 직전에 검증하고 셸 없이 프로그램을 시작합니다.[1], [2], [3]

CVSS 벡터CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H[1]
💡 알기 쉬운 설명 (ELI5)

문장부호에 따라 업무가 바뀔 수 있는 문장을 받은 직원을 떠올려 보세요. 기호 하나가 배송 지시를 두 번째 명령으로 바꿀 수 있습니다. Langflow는 설정된 명령을 셸에 넘겨 실행 파일과 인수를 별도 데이터로 다루지 않고 그 구문을 제어 지시로 해석하게 했습니다. 수정은 허용된 명령을 검증한 뒤 셸 없이 프로그램을 직접 실행합니다.[1], [2]

핵심 개념 및 용어

MCP stdio 전송
MCP 서버를 로컬 자식 프로세스로 시작하고 표준 입력과 출력으로 프로토콜 메시지를 주고받습니다.[1], [2]
명령 주입(CWE-78)
외부 입력의 영향을 받은 텍스트가 셸이나 프로세스 실행기에 전달되는 운영체제 명령을 바꿉니다.[1], [5]
실행 지점
프로세스를 만드는 최종 코드 경로입니다. API가 먼저 검사했더라도 여기서 검증해야 합니다.[1], [2]
Flow/tweak 내장 설정
설정 API가 아니라 flow 또는 런타임 재정의에 포함된 MCP 설정입니다.[1], [2]

프레임워크 매핑

  • 이 가이드에서 설명하는 약점의 CWE 참조: CWE-78

근본 원인 분석 (Root Cause)

1.10.3 이전에는 MCP stdio 설정이 명령과 인수를 문자열로 합친 뒤 bash -c로 실행했습니다. 1.9.0에서 설정 API에 허용 목록과 인수·환경 검사가 추가됐지만, flow나 tweak에 포함된 MCP Tools 설정은 실행 지점에 공통 정책이 없어 모델 검증을 우회할 수 있었습니다. Langflow 1.10.3은 lfx.base.mcp.security.validate_mcp_stdio_config에서 검증을 통합하고 API, flow, tweak, 레거시 컴포넌트, 프로세스 실행 직전에 적용하며 셸 래퍼를 제거합니다. CVE-2026-105697은 CWE-78이며 CVSS 3.1 점수는 9.9입니다. 자동 로그인을 꺼도 해당 MCP 경로를 설정하거나 실행할 수 있는 인증된 비관리자 사용자가 필요합니다. 기본 자동 로그인은 외부에 노출된 개발 인스턴스를 자격 증명 없이 접근 가능하게 만들 수 있습니다.[1], [2], [4], [5]

단계별 공격 실행 흐름

단계 1

사용자가 MCP 설정 경로에 접근

권고문은 MCP 서버 설정 또는 MCP Tools 컴포넌트를 사용하는 flow를 통한 접근을 설명합니다. 네트워크에 노출되어 있고 개발용 기본 설정 LANGFLOW_AUTO_LOGIN=true가 켜진 인스턴스에서는 공격자가 자격 증명 없이 토큰을 얻을 수 있었습니다. 자동 로그인을 꺼도 인증된 비관리자 사용자만으로 가능할 수 있습니다.[1]

단계 2

설정이 프로세스 준비 단계에 도달

MCP stdio 연결을 준비하는 동안 명령과 인수가 command_str가 됩니다.[1]

단계 3

셸이 문자열을 해석

1.10.3 이전 실행 경로는 bash -c를 사용했으며 MCP handshake가 성공하기 전 연결을 시도할 때 실행됐습니다.[1]

단계 4

진입점 검사가 불완전

1.9.0은 REST 설정을 검증하지만 flow와 tweak 설정은 모델 검증을 우회할 수 있습니다.[1]

단계 5

호스트 프로세스는 Langflow 권한으로 실행

명령은 Langflow 서비스 사용자로 실행됩니다. UI에는 MCP 서버 시작 실패가 표시될 수도 있습니다.[1]

단계 6

1.10.3이 실행 경계를 차단

공통 정책이 모든 진입점과 프로세스 실행 직전에 설정을 검증하며 셸 없이 프로그램을 시작합니다.[1], [2]

소스 코드 비교: 취약한 구현 vs 보안 패치

취약한 발췌는 권고문에 기록된 셸 기반 실행 형태를 보여주며 실행 가능한 exploit이 아닙니다. 수정 발췌는 1.10.3 설계를 요약합니다. 공통 정책이 모든 진입점과 프로세스 생성 직전에 설정을 검증하고, API는 실행 파일과 인수를 분리해 전달합니다. 직접 실행은 셸 해석을 없애지만 허용된 모든 실행 파일이나 패키지를 자동으로 안전하게 만들지는 않습니다. 운영자는 패키지 출처와 격리에 대한 적절한 통제도 적용해야 합니다.[1], [2]

소스 코드 발췌: lfx/base/mcp/util.py — 관련 소스 코드 발췌

취약한 구현
# 권고문에 나온 영향받는 실행 형태(발췌):
server_params = StdioServerParameters(
    command="bash",
    args=["-c", f"exec {command_str}"],
    env=env_data,
)
보안 강화 패치
# 1.10.3 소스를 바탕으로 한 축약 예시: 정책을 검증한 뒤 프로세스를 직접 실행합니다.
command_parts = shlex.split(command_str)
if not command_parts:
    raise ValueError("MCP stdio command is required")
command, args = command_parts[0], command_parts[1:]
validate_mcp_stdio_config(command, args, env_data)  # Repeat at the execution boundary.
server_params = StdioServerParameters(
    command=command,
    args=args,
    env=env_data,
)  # No shell wrapper. The shared validator rejects disallowed configurations.

엔지니어링 및 시스템 보안 강화 체크리스트

출처