FlawOpen

flawopen.com/AI Security/litellm-mcp-preview-command-injection-cve-2026-42271

● CVE-2026-42271 · CVSS v4 8.7[1] · 높음
보안 연구 · FlawOpen

LiteLLM MCP 명령 주입: CVE-2026-42271

GTIG는 CVE-2026-42271의 실제 악용을 확인했습니다. 유효한 LiteLLM 키로 MCP 미리보기에서 명령을 실행할 수 있었습니다. 1.83.7 이상으로 업데이트하세요.[1], [6], [8]

CVSS 벡터CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:N/SA:N[1]
💡 알기 쉬운 설명 (ELI5)

작업장은 방문자가 도구를 등록하기 전에 시험해 볼 수 있게 합니다. 시험대는 작업장의 강력한 기계를 작동시킬 수 있으므로 관리자만 지시를 내려야 합니다. 취약한 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]

프레임워크 매핑

단계별 공격 실행 흐름

단계 1

LiteLLM 버전과 엔드포인트 노출을 확인합니다

유지관리자 권고에 따르면 LiteLLM >=1.74.2 및 <1.83.7이 영향을 받으며 유효한 proxy API 키가 필요합니다. 수정 전에는 낮은 권한의 내부 사용자 키를 포함한 모든 인증된 키 보유자가 미리보기 경로에 접근할 수 있었습니다. GTIG는 CVE-2026-42271을 악용 확인 목록에 포함하지만, 이 CVE의 전제 조건은 유지관리자 권고의 인증된 위협 모델을 따르세요.[1], [6]

단계 2

낮은 권한의 키가 관리자용 미리보기 작업에 도달합니다

엔드포인트는 stdio 명령, 인수, 환경 변수를 포함한 전체 MCP 서버 구성을 받았습니다. 서버는 키를 인증했지만 PROXY_ADMIN 역할을 확인하지 않아 인증된 키 보유자라면 누구나 미리보기를 호출할 수 있었습니다.[1]

단계 3

미리보기가 프록시 호스트에서 프로세스를 시작합니다

제공된 stdio 구성을 시험하기 위해 LiteLLM은 MCP 클라이언트를 만들고 프록시 서비스 권한으로 구성된 자식 프로세스를 시작했습니다. 이는 AI 모델이 안전하지 않은 문장을 반환하는 문제가 아니라 게이트웨이 호스트에서의 명령 실행입니다.[2], [8]

단계 4

별도의 Starlette 결함이 인증 경계를 약화할 수 있습니다

Horizon3는 취약한 Starlette 버전이 있을 때 CVE-2026-48710으로 인해 경로 기반 인증이 Starlette가 선택한 경로와 다른 request.url.path를 볼 수 있다고 보고했습니다. 연구자들은 영향을 받는 배포에서 API 키 요건을 없애도록 CVE-2026-42271과 연계했다고 보고했습니다. 이 체인의 출처는 연구자에게 명확히 돌리고, 두 CVE의 원인과 패치는 구분하세요.[5], [3], [4]

단계 5

두 경계를 수정하고 실제로 해결된 패키지를 확인합니다

LiteLLM 1.83.7에서 미리보기 경로를 수정해 PROXY_ADMIN을 요구하고 tools/list에 명시적 인증을 추가했습니다. 또한 새 요청과 업데이트 요청에서 명령 허용 목록을 검사하고, 기존 구성을 잡기 위해 _create_mcp_client에서 다시 검사합니다. 허용 목록은 샌드박스가 아니며 허용된 런타임도 인수를 해석할 수 있습니다. Starlette는 CVE-2026-48710을 별도로 1.0.1에서 수정했습니다. 실제 해석된 패키지 조합을 확인하고 보고된 체인은 독립적으로 평가하세요.[1], [8], [4], [7]

단계 6

최근 캠페인 정황 (2026년 10월 7일 보고)

Black Lotus Labs는 PoeLLM 악성코드 샘플이 /mcp-rest/test/connection을 노렸을 가능성이 높다고 보고했습니다. BleepingComputer도 이 캠페인에서 CVE-2026-42271을 악용하려는 시도가 있었다고 전했습니다. 이 보고는 감염된 모든 호스트가 이 CVE를 통해 침해됐거나 모든 LiteLLM 대상이 취약했다는 뜻은 아닙니다. 이는 현재 공격 대상에 관한 근거이지, 이 취약점에 귀속되는 피해자 수가 아닙니다.[9], [10]

근본 원인 분석 (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,
    )

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

출처

← AI Security Directory →