flawopen.com/Teardowns/cve-2026-105697-langflow-mcp-stdio-command-injection
CVE-2026-105697: Langflow MCP 명령 주입
Langflow 1.10.3 이전 버전은 MCP stdio 설정을 셸로 시작하는 프로세스에 전달했습니다. 네트워크에 노출된 인스턴스에서 개발용 기본값인 LANGFLOW_AUTO_LOGIN=true가 켜져 있으면 공격자는 자격 증명 없이 토큰을 얻을 수 있었습니다. 자동 로그인을 꺼도 인증된 비관리자 사용자가 호스트에서 명령을 실행할 수 있었습니다. 1.10.3은 모든 진입점과 프로세스 실행 직전에 검증하고 셸 없이 프로그램을 시작합니다.[1], [2], [3]
문장부호에 따라 업무가 바뀔 수 있는 문장을 받은 직원을 떠올려 보세요. 기호 하나가 배송 지시를 두 번째 명령으로 바꿀 수 있습니다. Langflow는 설정된 명령을 셸에 넘겨 실행 파일과 인수를 별도 데이터로 다루지 않고 그 구문을 제어 지시로 해석하게 했습니다. 수정은 허용된 명령을 검증한 뒤 셸 없이 프로그램을 직접 실행합니다.[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]
단계별 공격 실행 흐름
사용자가 MCP 설정 경로에 접근
권고문은 MCP 서버 설정 또는 MCP Tools 컴포넌트를 사용하는 flow를 통한 접근을 설명합니다. 네트워크에 노출되어 있고 개발용 기본 설정 LANGFLOW_AUTO_LOGIN=true가 켜진 인스턴스에서는 공격자가 자격 증명 없이 토큰을 얻을 수 있었습니다. 자동 로그인을 꺼도 인증된 비관리자 사용자만으로 가능할 수 있습니다.[1]
설정이 프로세스 준비 단계에 도달
MCP stdio 연결을 준비하는 동안 명령과 인수가 command_str가 됩니다.[1]
셸이 문자열을 해석
1.10.3 이전 실행 경로는 bash -c를 사용했으며 MCP handshake가 성공하기 전 연결을 시도할 때 실행됐습니다.[1]
진입점 검사가 불완전
1.9.0은 REST 설정을 검증하지만 flow와 tweak 설정은 모델 검증을 우회할 수 있습니다.[1]
호스트 프로세스는 Langflow 권한으로 실행
명령은 Langflow 서비스 사용자로 실행됩니다. UI에는 MCP 서버 시작 실패가 표시될 수도 있습니다.[1]
소스 코드 비교: 취약한 구현 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.
엔지니어링 및 시스템 보안 강화 체크리스트
- ✓
langflow는 1.10.3+,langflow-base는 0.10.3+,lfx는 1.10.3+로 업그레이드하고 실제 배포된 패키지 버전을 확인합니다.[1], [3] - ✓1.9.0의 REST 모델 검사를 완전한 수정으로 간주하지 말고 이전 버전의 flow/tweak 내장 MCP 설정을 검토합니다.[1]
- ✓모든 진입점과 프로세스 생성 직전에 명령, 인수, 환경, 패키지 출처, 격리 정책을 검증합니다.[1], [2]
- ✓프로세스 API에 실행 파일과 인수 배열을 분리해 전달하고 셸 명령 문자열 생성을 피합니다.[2]
- ✓멀티테넌트 배포에서는 허용된
npx/uvx패키지를 고정하고 문서화된 인터프리터 및 Docker 강화 설정을 활성화합니다.[1] - ✓FlawOpen 사고 대응 권고: 취약한 버전이 노출된 동안 MCP stdio 연결을 설정하거나 실행할 수 있었던 사용자를 확인하고 호스트 텔레메트리에서 비정상 Langflow 자식 프로세스를 조사합니다.[1]
- ✓REST API, flow, tweak, 레거시 컴포넌트, 실행 전 경로의 회귀 테스트를 추가하고 거부된 설정이 프로세스를 만들지 않는지 확인합니다.[2]