flawopen.com/AI Security/litellm-mcp-preview-command-injection-cve-2026-42271
LiteLLM MCP 명령 주입: CVE-2026-42271
GTIG는 CVE-2026-42271의 실제 악용을 확인했습니다. 유효한 LiteLLM 키로 MCP 미리보기에서 명령을 실행할 수 있었습니다. 1.83.7 이상으로 업데이트하세요.[1], [6], [8]
작업장은 방문자가 도구를 등록하기 전에 시험해 볼 수 있게 합니다. 시험대는 작업장의 강력한 기계를 작동시킬 수 있으므로 관리자만 지시를 내려야 합니다. 취약한 LiteLLM 버전에서는 승인된 출입증만 있으면 누구나 시험대에 접근할 수 있었습니다. 별도의 Starlette 결함은 재구성된 URL로 접근 여부를 판단하는 경비원을 속일 수도 있습니다. 두 경계는 각각 수정해야 합니다. 다른 창구에서 방문자는 소포 주소표에 슬래시나 물음표를 쓸 수 있습니다. 직원이 주소를 다시 조합하며 그 문자를 붙여 넣으면 새 경로로 잘못 읽지만, 소포는 여전히 원래 복도를 따라갑니다. 이것이 Starlette의 별도 Host-경로 혼동입니다.[1], [3], [5]
핵심 개념 및 용어
Model Context Protocol (MCP)- AI 게이트웨이 같은 애플리케이션이 외부 도구 및 데이터 소스와 연결하는 프로토콜입니다. LiteLLM 미리보기 엔드포인트는 저장 전에 MCP 서버 구성을 시험합니다.[1]
stdio 전송- 로컬 자식 프로세스를 시작하고 표준 입력 및 출력으로 메시지를 주고받는 MCP 연결 방식입니다. 프로세스는 LiteLLM 프록시 호스트에서 프록시 서비스의 운영체제 권한으로 실행됩니다.[1], [2]
역할 기반 권한 부여- 요구된 역할이 있는 ID에만 작업을 허용하는 서버 측 검사입니다. CVE-2026-42271에서는 저장 작업에 있던 PROXY_ADMIN 검사가 미리보기 경로에 빠져 있었습니다.[1], [2]
CVE-2026-48710 (Starlette BadHost)- 별도의 Starlette 결함입니다. 잘못된 Host 헤더로 인해 request.url.path가 라우팅에 사용된 경로와 달라질 수 있었습니다. Horizon3는 특정 의존성 조합에서 LiteLLM 경로 기반 인증을 우회할 수 있다고 보고했으며, 이는
CVE-2026-42271자체에 포함되지 않습니다.[3], [5], [4] MCP stdio 명령 허용 목록- LiteLLM이 stdio 전송에서 허용하는 실행 파일 basename 집합입니다. 구성 검증 시와 기존 레코드의 클라이언트 생성 전에 다시 확인합니다. 허용된 런타임도 전달된 인수를 해석할 수 있으므로 샌드박스가 아닙니다.[8]
프레임워크 매핑
- 이 가이드에서 설명하는 약점의 CWE 참조: CWE-78
- CISA KEV — 추가일 2026-06-08 — CVE-2026-42271
단계별 공격 실행 흐름
낮은 권한의 키가 관리자용 미리보기 작업에 도달합니다
엔드포인트는 stdio 명령, 인수, 환경 변수를 포함한 전체 MCP 서버 구성을 받았습니다. 서버는 키를 인증했지만 PROXY_ADMIN 역할을 확인하지 않아 인증된 키 보유자라면 누구나 미리보기를 호출할 수 있었습니다.[1]
두 경계를 수정하고 실제로 해결된 패키지를 확인합니다
LiteLLM 1.83.7에서 미리보기 경로를 수정해 PROXY_ADMIN을 요구하고 tools/list에 명시적 인증을 추가했습니다. 또한 새 요청과 업데이트 요청에서 명령 허용 목록을 검사하고, 기존 구성을 잡기 위해 _create_mcp_client에서 다시 검사합니다. 허용 목록은 샌드박스가 아니며 허용된 런타임도 인수를 해석할 수 있습니다. Starlette는 CVE-2026-48710을 별도로 1.0.1에서 수정했습니다. 실제 해석된 패키지 조합을 확인하고 보고된 체인은 독립적으로 평가하세요.[1], [8], [4], [7]
근본 원인 분석 (Root Cause)
LiteLLM 결함은 두 MCP 미리보기 경로에 역할 검사가 없었다는 점입니다. 유효한 프록시 API 키만 있으면 PROXY_ADMIN 역할 없이도 해당 경로를 호출할 수 있었습니다. 연결 미리보기는 호출자가 제공한 stdio 구성을 받아 프록시 프로세스 권한으로 명령을 실행했습니다. 별도의 Starlette 결함은 잘못된 Host 헤더로 인해 request.url.path가 Starlette가 실제 라우팅한 경로와 달라질 수 있게 했습니다. Horizon3는 이 동작을 LiteLLM과 연결하면 경로 기반 API 키 검증을 우회할 수 있는 체인을 보고했습니다. 두 취약점은 서로 별개이므로 LiteLLM의 권한 검사 및 명령 실행 경계를 수정하고 Starlette를 1.0.1 이상으로 업데이트해야 합니다.[1], [8], [3], [4], [5]
소스 코드 비교: 취약한 구현 vs 보안 패치
이 발췌는 실행 경계에 적용된 LiteLLM 병합 패치를 보여줍니다. stdio 클라이언트를 만들기 전에 명령 basename을 확인하므로 기존 DB/구성 레코드도 검사를 통과해야 합니다. 패치는 새 서버 및 업데이트 요청도 검증하고 두 미리보기 엔드포인트를 PROXY_ADMIN으로 제한합니다. /test/tools/list에는 user_api_key_auth 의존성도 명시적으로 추가됐습니다. 허용 목록은 샌드박스가 아닙니다. 허용된 런타임도 인수를 해석할 수 있으므로 미리보기는 관리자만 사용하게 하고 프록시는 최소 권한으로 실행하세요.[1], [2], [8]
소스 코드 발췌: LiteLLM stdio 클라이언트 검증 코드 발췌
# _create_mcp_client: stdio 명령 가드가 추가되기 전 코드.
if server.command and server.args is not None:
stdio_config = MCPStdioConfig(
command=server.command,
args=server.args,
env=resolved_env,
)
# _create_mcp_client: 기존 DB/설정 레코드도 다시 검증합니다.
if server.command:
base_command = os.path.basename(server.command)
if base_command not in MCP_STDIO_ALLOWED_COMMANDS:
raise HTTPException(
status_code=403,
detail="MCP stdio command is not in the allowlist",
)
if server.command and server.args is not None:
stdio_config = MCPStdioConfig(
command=server.command,
args=server.args,
env=resolved_env,
)
엔지니어링 및 시스템 보안 강화 체크리스트
- ✓LiteLLM 프록시 배포를 목록화하고 실제로 해결된 버전을 확인한 다음 영향을 받는 릴리스를 1.83.7 이상으로 업데이트합니다.[1], [8]
- ✓배포된 잠금 파일이나 컨테이너 이미지를 확인하고, 해결된 FastAPI 버전이 허용하는 경우 Starlette 1.0.1 이상인지 확인합니다. 검증되지 않은 의존성 재정의를 하지 않습니다.[3], [7]
- ✓LiteLLM을 업데이트하기 전까지 유지관리자 권고대로 리버스 프록시 또는 API 게이트웨이에서 POST /mcp-rest/test/connection 및 POST /mcp-rest/test/tools/list를 차단합니다.[1]
- ✓두 경로가 모두 user_api_key_auth를 요구하고 MCP 클라이언트를 만들기 전에 PROXY_ADMIN이 아닌 모든 역할을 거부하는지 확인합니다.[1], [8]
- ✓미인증 요청과 유효한 비관리자 키가 미리보기 작업에 도달하지 못하며, 권한이 있는 관리자는 지원되는 흐름을 사용할 수 있음을 증명하는 테스트를 추가합니다.[8]
- ✓Starlette의 잘못된 Host 처리를 테스트하고 접근 제어 미들웨어가 표준 ASGI 경로 또는 프레임워크가 검증한 URL을 사용하는지 확인합니다.[3], [4]
- ✓프록시 로그와 자식 프로세스 텔레메트리에서 MCP 미리보기 경로의 예상치 못한 사용을 조사합니다. 호스트 접근 가능성이 발견되면 프록시에 저장된 자격 증명을 교체합니다.[1], [8]
- ✓두 취약점 기록을 분리합니다. CVE-2026-42271은 LiteLLM 명령 실행이고, CVE-2026-48710은 Starlette Host 파싱 및 경로 혼동입니다.[1], [3]
- ✓각 환경의 LITELLM_MCP_STDIO_EXTRA_COMMANDS를 검토하세요. 사용자 지정 항목은 실행 파일 신뢰 경계를 넓힐 뿐 인수 처리를 안전하게 만들지 않습니다.[8]
출처
- LiteLLM security advisory GHSA-v4p8-mg3p-g94g / CVE-2026-42271
- LiteLLM pull request #25343: MCP stdio endpoint authorization and command validation fix
- Starlette advisory GHSA-86qp-5c8j-p5mr / CVE-2026-48710
- Starlette commit 764dab0: ignore malformed Host when constructing request.url
- Horizon3: CVE-2026-42271 chained with CVE-2026-48710
- Google Threat Intelligence Group: Vulnerability Discovery and Exploitation Trends in the AI Era
- LiteLLM issue #28993: FastAPI constraint and Starlette CVE-2026-48710 dependency resolution report
- LiteLLM merged PR #25343 — command allowlist, execution guard, role checks, and tests
- Lumen Black Lotus Labs: 노출된 서비스를 노리는 PoeLLM 악성코드
- BleepingComputer: 노출된 AI 서버를 겨냥한 PoeLLM 공격