LiteLLM v1.82.6 이하 안전
⚠️ v1.82.7~1.82.8 감염
LiteLLM 공급망 공격, pip만 썼는데 왜 Docker는 괜찮았을까요?
2026년 3월 24일, AI 개발자들이 가장 많이 쓰는 LLM 프록시 라이브러리 LiteLLM이 공급망 공격으로 뚫렸습니다. 월간 다운로드 수 약 9,700만 건(출처: Phoenix Security 분석 보고서, 2026.03.24)에 달하는 패키지가 단 3시간 만에 감염 배포됐고, 그 사이 SSH 키·클라우드 인증 정보·API 키가 통째로 빠져나갈 수 있었습니다. 그런데 공식 Docker 이미지를 쓴 사람은 멀쩡했습니다. 왜 그럴까요?
공격이 시작된 진짜 출발점 — Trivy였습니다
LiteLLM 공급망 공격은 3월 24일 갑자기 터진 게 아닙니다. 2월 28일, 보안 취약점 스캐너인 Aqua Security의 Trivy 저장소가 먼저 뚫렸고, 그 여파가 한 달 가까이 이어지다 결국 LiteLLM까지 덮쳤습니다. 해킹 그룹 TeamPCP는 Trivy의 GitHub Actions 워크플로우 취약점을 이용해 조직 전체의 GitHub 개인 액세스 토큰(PAT)을 탈취했고, 3월 19일에는 Trivy GitHub Actions 태그 76개를 전부 악성 버전으로 교체해 버렸습니다(출처: Aqua Security GitHub 보안 권고 GHSA-69fq-xp46-6×23, 2026.03.19).
LiteLLM은 자체 CI/CD 파이프라인에서 Trivy를 보안 스캐너로 쓰고 있었습니다. 문제는 버전을 고정하지 않고 apt-get install -y trivy 방식으로 최신 버전을 자동으로 받아 쓰는 구조였다는 점입니다. 변조된 Trivy가 LiteLLM의 빌드 파이프라인에서 실행되자, 그 안에 저장된 PyPI 배포 토큰이 공격자에게 그대로 넘어갔습니다(출처: LiteLLM 공식 보안 업데이트, docs.litellm.ai, 2026.03.24). 보안 도구 하나가 뚫렸을 뿐인데, 결과적으로 수천만 명이 쓰는 라이브러리의 배포 권한이 해커 손에 들어간 것입니다.
💡 공식 발표문과 타임라인을 같이 놓고 보면, 이 공격은 단발성이 아니라 최소 5개 소프트웨어 생태계를 넘나든 연쇄 캠페인이었습니다. Trivy → npm → Checkmarx KICS → LiteLLM → Telnyx 순서로 계속 확장됐습니다.
TeamPCP의 공격 타임라인을 보면 패턴이 선명합니다. 각 단계에서 탈취한 인증 정보가 다음 단계의 침투 도구로 재활용됐습니다. Trivy 침해 → npm 토큰 탈취 → CanisterWorm 자가 전파 웜 → Checkmarx 침해 → LiteLLM PyPI 토큰 획득 → 악성 패키지 배포. Datadog Security Labs는 이를 “하나의 침해가 다음 침해의 연료가 되는 자격 증명 연쇄 전파”라고 표현했습니다(출처: Datadog Security Labs, securitylabs.datadoghq.com, 2026.03.25).
3시간 안에 터진 이유 — LiteLLM이 왜 완벽한 표적이었나
LiteLLM은 OpenAI, Anthropic, Google, AWS Bedrock, Azure 등 100개 이상의 LLM 제공업체 API를 단일 인터페이스로 묶어주는 프록시 게이트웨이입니다. GitHub 스타 수 4만 700개 이상, GitHub Stars 기준 스탠퍼드의 DSPy, CrewAI, Google ADK 등 주요 AI 프레임워크의 의존성으로도 사용됩니다. 해커 입장에서 보면, LiteLLM 하나만 뚫으면 그 서버에 있는 모든 LLM 제공업체의 API 키를 한꺼번에 가져갈 수 있는 구조입니다. Phoenix Security의 분석에 따르면 LiteLLM의 월간 PyPI 다운로드는 약 9,500만 건에 달합니다(출처: Phoenix Security 분석 보고서, phoenix.security, 2026.03.24). 타겟으로서의 가성비가 최고인 패키지였던 셈입니다.
Wiz Research는 클라우드 환경의 약 36%에 LiteLLM이 설치돼 있다는 수치를 내놓았습니다(출처: Wiz Research, wiz.io, 2026.03.24). 3분의 1이 넘는 클라우드 환경에 깔려 있다는 뜻입니다. 악성 버전이 PyPI에 올라가 있던 시간은 약 3시간(10:39 UTC ~ 13:38 UTC)에 불과했지만, LiteLLM의 일일 다운로드 수가 340만 건을 넘기 때문에 그 사이에도 상당수 시스템이 감염됐을 것으로 추정됩니다(출처: 나무위키 ‘2026년 LiteLLM 공급망 공격 사건’, 2026.03.27 기준).
💡 공격 직후 Andrej Karpathy(테슬라 전 AI 디렉터, OpenAI 공동창립자)가 이 사건을 “software horror”라고 표현했습니다. AI 인프라를 직접 겨냥한 최초의 대규모 공급망 공격으로 기록될 가능성이 높습니다.
pip 설치만 했는데 전부 탈취됩니다 — 악성코드 동작 구조
악성 코드가 삽입된 버전은 두 가지입니다. v1.82.7에는 litellm/proxy/proxy_server.py 안에 Base64 이중 인코딩으로 난독화된 페이로드가 삽입됐습니다. 디코딩하면 332줄짜리 인증 정보 수집 스크립트가 나옵니다. 수집 대상의 범위가 상당합니다. SSH 키(RSA, Ed25519, ECDSA, DSA 전 유형), AWS·GCP·Azure 클라우드 인증 정보, Kubernetes 서비스 계정 토큰 및 전 네임스페이스의 시크릿, Docker 레지스트리 인증 정보, CI/CD 파이프라인 토큰, 암호화폐 지갑 키, 셸 히스토리, 환경 변수 전체가 수집 대상에 포함됩니다(출처: Datadog Security Labs 분석 보고서, securitylabs.datadoghq.com, 2026.03.25).
수집된 데이터는 AES-256-CBC로 암호화된 뒤, 세션 키를 하드코딩된 RSA-4096 공개키로 한 번 더 감싸서 tpcp.tar.gz로 묶어 models.litellm.cloud로 전송됩니다. 이 도메인은 LiteLLM 공식 도메인인 litellm.ai를 모방한 가짜로, 공격 하루 전인 3월 23일에 등록됐습니다. 네트워크 트래픽을 캡처해도 RSA 개인 키 없이는 내용을 볼 수 없습니다. 그리고 추가 백도어가 ~/.config/systemd/user/sysmon.service라는 이름의 systemd 서비스로 설치되어, 약 50분마다 checkmarx.zone/raw에서 추가 페이로드를 내려받아 실행하는 구조입니다(출처: LiteLLM 공식 보안 업데이트, docs.litellm.ai, 2026.03.24).
Kubernetes 환경에서는 피해가 한 단계 더 심각합니다. 사용 가능한 Kubernetes 서비스 계정 토큰을 발견하면, 클러스터 내 모든 노드에 privileged 권한을 가진 node-setup-* 파드를 배포합니다. 이 파드는 호스트 루트 파일시스템 전체를 마운트하고, 컨트롤 플레인 노드에도 배포됩니다. 패키지 하나를 설치했을 뿐인데 클러스터 전체가 장악되는 구조입니다.
Docker 사용자는 왜 안전했을까요 — 예상 밖의 이유
직접 확인한 사실인데, LiteLLM 공식 Docker 이미지(ghcr.io/berriai/litellm) 사용자는 이번 공격에서 피해를 입지 않았습니다. LiteLLM 공식 보안 업데이트에 딱 이렇게 나와 있습니다. “That deployment path pins dependencies in requirements.txt and does not rely on the compromised PyPI packages”(출처: docs.litellm.ai, 2026.03.24). 공식 Docker 이미지의 requirements.txt에 LiteLLM 버전이 고정돼 있어서, 사건 당시 이미지의 LiteLLM 버전은 1.82.3이었고 악성 버전이 딸려 오지 않았습니다.
💡 “pip install litellm”을 그냥 치면 항상 최신 버전이 설치됩니다. Docker 공식 이미지는 버전을 고정하기 때문에 이번 공격에서 살아남았습니다. 버전 고정 한 줄이 모든 차이를 만든 셈입니다.
많은 개발자들이 “Docker를 쓰면 격리돼서 안전하다”고 생각합니다. 맞는 말이지만, 이번 케이스에서 Docker가 안전했던 이유는 격리 때문이 아니라 의존성 버전 고정 때문이었습니다. Docker 이미지 빌드 시 pip install litellm을 버전 고정 없이 실행하는 경우, 빌드 시점에 악성 버전을 설치하게 됩니다. 실제로 LiteLLM 공식 문서는 “Docker 이미지를 직접 빌드할 때 고정 버전 없이 pip install을 실행한 경우” 감염 가능하다고 명시하고 있습니다(출처: docs.litellm.ai, 2026.03.24). 안전 여부를 가른 건 Docker 사용 여부가 아닌, 버전을 고정했는지 여부였습니다.
비교해 보면 이렇습니다. 감염 위험 있음: 3월 24일 10:39~16:00 UTC 사이에 버전 고정 없이 pip install litellm을 실행한 경우, 간접 의존성으로 LiteLLM을 느슨하게 받아오는 AI 에이전트 프레임워크를 쓴 경우. 감염 없음: 공식 Docker 이미지 사용자, LiteLLM Cloud 사용자, v1.82.6 이하 고정 사용자, GitHub 소스에서 직접 설치한 경우(출처: LiteLLM 공식 보안 업데이트, docs.litellm.ai, 2026.03.24).
.pth 파일 — import도 안 했는데 실행됩니다
v1.82.8이 v1.82.7보다 훨씬 위험한 이유가 있습니다. litellm_init.pth라는 파일(34,628 바이트)이 추가로 포함됐기 때문입니다. Python의 .pth 파일은 site-packages 디렉터리에 위치하면 Python 인터프리터 시작 시 site.py가 자동으로 실행하는 특성이 있습니다(출처: Python 공식 문서, docs.python.org/3/library/site.html). import litellm 같은 명시적 임포트가 전혀 없어도 됩니다. 그냥 환경에 litellm 1.82.8이 설치돼 있으면, pytest를 돌릴 때, Jupyter 노트북을 열 때, cron 작업에서 Python 스크립트를 실행할 때 모두 악성 코드가 실행됩니다.
💡 Phoenix Security의 기술 분석 보고서는 이 동작을 “Python 인터프리터 자체에 훅을 건 루트킷과 기능적으로 동일하다”고 표현했습니다. LiteLLM을 한 번도 코드에서 호출하지 않은 환경도 감염된다는 뜻입니다(출처: phoenix.security, 2026.03.24).
litellm_init.pth 파일의 내용 자체는 한 줄짜리 코드이고, Base64 이중 인코딩으로 난독화돼 있어 단순히 grep으로 소스를 훑어보는 것만으로는 발견이 어렵습니다. 공격자가 RECORD 파일까지 새로 서명해서 업로드했기 때문에, 패키지 설치 시 표준 무결성 검사도 통과합니다(출처: Phoenix Security 분석 보고서, phoenix.security, 2026.03.24). 일반적인 보안 스캔으로는 걸러내기 어려운 구조였습니다.
이 사건이 발각된 것도 사실은 공격자의 실수 때문이었습니다. FutureSearch.ai의 Callum McMahon이 Cursor의 MCP 플러그인을 테스트하다가 LiteLLM이 간접 의존성으로 설치됐는데, v1.82.8 설치 직후 시스템 메모리가 급격히 고갈되며 머신이 다운됐습니다. 조사해 보니 .pth 파일이 Python 시작 시마다 자식 프로세스를 무한 생성하는 포크 폭탄 구조가 돼 버린, 공격자가 의도하지 않은 버그였습니다. 이 버그가 없었다면 발견이 훨씬 늦어졌을 수 있습니다.
감염 확인과 지금 당장 해야 할 것들
먼저 설치된 버전을 확인합니다. 터미널에서 pip show litellm | grep Version을 실행해 1.82.7 또는 1.82.8이 나오면 즉시 조치가 필요합니다. .pth 파일 존재 여부도 확인해야 합니다. find / -name "litellm_init.pth" 2>/dev/null을 실행해 결과가 나오면 감염된 것입니다. 백도어 서비스도 확인하세요. ls ~/.config/sysmon/sysmon.py ~/.config/systemd/user/sysmon.service 2>/dev/null 명령으로 해당 파일이 존재하는지 봅니다(출처: LiteLLM 공식 보안 업데이트, docs.litellm.ai, 2026.03.24).
감염이 확인됐다면, 패키지 삭제만으로는 충분하지 않습니다. LiteLLM 공식 문서는 “악성 버전을 제거하는 것을 완전한 복구로 취급하지 말라”고 명시합니다. 감염된 환경에서 접근 가능했던 모든 인증 정보를 교체해야 합니다. SSH 키 재생성, AWS·GCP·Azure 인증 정보 롤링, LLM API 키 교체, 데이터베이스 비밀번호 변경, Kubernetes 시크릿 재발급이 모두 포함됩니다(출처: docs.litellm.ai, 2026.03.24). 사실상 환경 전체를 갈아엎는 수준의 작업입니다. Kubernetes 환경이라면 kubectl get pods -n kube-system | grep node-setup으로 악성 파드가 배포됐는지도 반드시 확인해야 합니다.
| 확인 항목 | 명령어 | 결과 해석 |
|---|---|---|
| 버전 확인 | pip show litellm | grep Version | 1.82.7 또는 1.82.8 → 즉시 조치 |
| .pth 파일 | find / -name “litellm_init.pth” | 파일 존재 → 감염 확정 |
| 백도어 서비스 | ls ~/.config/sysmon/sysmon.py | 파일 존재 → 백도어 설치됨 |
| K8s 악성 파드 | kubectl get pods -n kube-system | grep node-setup | node-setup-* 파드 → 클러스터 장악 시도 |
출처: LiteLLM 공식 보안 업데이트 (docs.litellm.ai, 2026.03.24)
장기적으로는 세 가지 습관이 핵심입니다. 첫째, 의존성 버전을 정확히 고정합니다(pip install "litellm<=1.82.6"). 둘째, GitHub Actions를 사용할 때 버전 태그가 아닌 전체 SHA 커밋 해시로 고정합니다. 이번 공격이 Trivy Actions 태그를 변조해서 시작됐다는 걸 기억하면 됩니다. 셋째, PyPI Trusted Publishers(OIDC 기반 배포)를 활성화해서 CI 파이프라인에서 장기 보존 토큰을 없앱니다. LiteLLM의 PyPI 배포 토큰이 탈취된 것이 이번 공격의 직접적 원인이었기 때문입니다(출처: Datadog Security Labs, securitylabs.datadoghq.com, 2026.03.25).
Q&A — 5가지 핵심 질문
Q1. LiteLLM을 설치만 했고 한 번도 실행하지 않았어도 감염된 건가요?
v1.82.7 기준으로는, litellm.proxy.proxy_server를 임포트한 경우에만 페이로드가 실행됩니다. 설치만 하고 코드에서 전혀 사용하지 않았다면 v1.82.7은 실행되지 않았을 가능성이 높습니다.
문제는 v1.82.8입니다. .pth 파일이 Python 인터프리터가 시작될 때마다 자동 실행되기 때문에, 설치된 환경에서 Python을 한 번이라도 실행했다면 임포트 여부와 무관하게 악성 코드가 돌아갔습니다(출처: docs.litellm.ai, 2026.03.24). pip show litellm | grep Version으로 버전부터 확인하세요.
Q2. CVE 번호가 없다는데, 그럼 일반 보안 스캐너로는 못 잡나요?
맞습니다. 이번 사건에는 전통적인 CVE가 할당되지 않았습니다. 코드 자체의 취약점이 아니라 인증 정보 탈취를 통한 공급망 침해이기 때문입니다. PYSEC-2026-2, SNYK-PYTHON-LITELLM-15762713 등 보안 권고는 발행됐지만, CVE 기반으로만 탐지하는 보안 스캐너는 이 위협을 전혀 잡지 못했습니다(출처: 나무위키 '2026년 LiteLLM 공급망 공격 사건', 2026.03.27).
Sonatype의 자동 탐지 시스템이 수 초 만에 감지했다고 밝혔지만, 이는 행동 기반 분석 도구였습니다. 버전 고정과 SHA 체크섬 비교가 가장 확실한 방어 수단입니다.
Q3. CrewAI나 DSPy를 사용하는 경우는 어떻게 되나요?
DSPy는 litellm>=1.64.0으로 의존성이 느슨하게 설정돼 있어, 감염 버전이 그대로 딸려 들어올 수 있었습니다. 이미 긴급 PR을 통해 <=1.82.6으로 고정했습니다(출처: DSPy GitHub, 2026.03.24).
CrewAI는 당일 LiteLLM 제거 가이드를 공개하고 네이티브 SDK로 전환을 선언했습니다. 이들 프레임워크를 사용 중이라면 lock 파일에서 litellm 버전을 직접 확인하세요. 감염 기간(2026.03.24 10:39~16:00 UTC)에 lock 파일 없이 설치한 경우라면 위험합니다.
Q4. LiteLLM은 이제 쓰면 안 되나요?
BerriAI는 사건 인지 후 침해된 패키지를 삭제하고 모든 배포 토큰을 폐기했으며, Google의 Mandiant 보안팀을 투입해 포렌식 분석을 진행 중입니다. 공급망 전체 스캔이 끝날 때까지 신규 릴리스를 중단하겠다고 선언한 상태입니다(출처: docs.litellm.ai, 2026.03.24).
v1.82.6 이하는 안전 버전으로 확인됐습니다. 다만 사건 이후 CrewAI, Google ADK 등 주요 프레임워크에서 LiteLLM 의존성 유지 여부를 재검토하기 시작했습니다. Bifrost(Go 기반), TensorZero(Rust 기반), Cloudflare AI Gateway 같은 대안이 거론되고 있습니다.
Q5. TeamPCP는 어떤 그룹인가요?
PCPcat, Persy_PCP, ShellForce, DeadCatx3, CipherForce 등 다수의 별명을 사용하는 해킹 그룹입니다. hackerbot-claw라는 AI 에이전트를 공격 타겟팅에 활용한 것으로 알려져 있습니다. 이 에이전트가 약 47,000개의 저장소를 스캔해 취약한 GitHub Actions 워크플로우를 자동으로 찾아냈다고 합니다(출처: 나무위키, 2026.03.27).
텔레그램에서 "장기전을 준비하고 있다"고 도발했고, Lapsus$와의 연관성이 추측되고 있지만 이유는 아직 공개되지 않았습니다. AI를 이용해 AI 인프라를 공격하는 그룹이라는 점에서 업계 전체가 주목하고 있습니다.
마치며 — "안전하다"고 생각한 것들을 다시 볼 때입니다
이번 LiteLLM 공급망 공격에서 가장 인상적인 부분은 두 가지입니다. 하나는 보안 스캐너(Trivy)가 공격의 출발점이 됐다는 것, 다른 하나는 Docker 사용자가 살아남은 이유가 격리가 아니라 버전 고정이었다는 것입니다. 보안 도구를 쓴다고 안심하는 것도, Docker를 쓴다고 안심하는 것도 이번 사건으로 다시 생각해볼 필요가 생겼습니다.
솔직히 말하면, 버전 고정과 GitHub Actions SHA 고정은 "귀찮다"고 미뤄두는 경우가 많습니다. 이번 사건은 그 귀찮음이 얼마나 비싼 대가를 치를 수 있는지를 보여줬습니다. pip 버전 고정 한 줄이 수백 개의 인증 정보를 지켰습니다.
TeamPCP가 다음 표적으로 AI 인프라 어딘가를 이미 노리고 있을 가능성이 높습니다. 지금 당장 사용 중인 AI 라이브러리의 버전이 고정돼 있는지, GitHub Actions 태그가 SHA로 고정돼 있는지 점검하는 게 가장 현실적인 대응입니다.
📎 본 포스팅 참고 자료
- LiteLLM 공식 보안 업데이트 (BerriAI) — docs.litellm.ai/blog/security-update-march-2026
- Datadog Security Labs — LiteLLM compromised on PyPI: Tracing the March 2026 TeamPCP supply chain campaign — securitylabs.datadoghq.com
- Phoenix Security — LiteLLM Backdoored by TeamPCP: PyPI Supply Chain Attack (2026) — phoenix.security
- Aqua Security GitHub 보안 권고 — GHSA-69fq-xp46-6x23 (Trivy 침해 관련)
- 나무위키 — 2026년 LiteLLM 공급망 공격 사건 (2026.03.27 기준)
본 포스팅은 2026년 3월 28일 기준으로 작성됐습니다. LiteLLM 보안 조사가 현재 진행 중이며, BerriAI의 공식 발표에 따라 세부 내용이 달라질 수 있습니다. 본 포스팅 작성 이후 서비스 정책·UI·기능이 변경될 수 있습니다. 정확한 최신 정보는 LiteLLM 공식 문서(docs.litellm.ai)를 직접 확인하세요.











댓글 남기기