LiteLLM 1.82.7 & 1.82.8 PyPI 패키지 공급망 공격 — 자격증명 탈취 악성코드 포함
Tell HN: Litellm 1.82.7 and 1.82.8 on PyPI are compromised
TL;DR Highlight
LiteLLM의 PyPI 패키지 1.82.7, 1.82.8 버전이 자격증명 탈취 악성 .pth 파일을 포함해 Python 인터프리터 시작만으로 자동 실행되어 광범위한 공급망 공격을 야기했다.
Who Should Read
LiteLLM을 사용 중인 백엔드 개발자 및 MLOps 엔지니어. 특히 AI 서비스 개발 환경에 litellm을 pip install로 설치해 사용하는 모든 개발자는 즉시 확인이 필요하다.
Core Mechanics
- litellm==1.82.8 (및 1.82.7) PyPI wheel 패키지 안에 악성 .pth 파일(litellm_init.pth, 34,628 바이트)이 포함되어 있다. .pth 파일은 Python이 site-packages를 로드할 때 자동으로 실행되는 파일이라, `import litellm`을 하지 않아도 Python 인터프리터가 시작되기만 하면 악성 코드가 바로 실행된다.
- 악성 페이로드는 이중 base64로 인코딩되어 있으며, 실행되면 호스트 시스템에서 민감 정보를 대량 수집한다. 수집 대상은 hostname, whoami, 네트워크 정보(ip addr, ip route), 모든 환경변수(API 키, 토큰 포함), SSH 개인키 전체(id_rsa, id_ed25519 등), ~/.git-credentials, AWS 자격증명(~/.aws/credentials + IMDS 메타데이터 토큰), Kubernetes config 파일들(~/.kube/config 등)이다.
- LiteLLM 메인테이너의 확인에 따르면, 이번 공격은 CI/CD 파이프라인에서 사용하는 보안 스캐너 Trivy(취약점 스캐너)가 먼저 해킹당한 것에서 시작됐다. 'TeamPCP'라는 공격 그룹이 Trivy를 통해 LiteLLM 저장소 접근 권한을 탈취했고, 창업자/CTO 계정(krrishdholakia)도 함께 침해된 것으로 보인다.
- Docker 프록시 이미지를 사용하는 경우는 영향을 받지 않았다. LiteLLM의 proxy Docker 이미지는 requirements.txt에 버전을 고정(pin)해두기 때문에 악성 버전이 자동으로 당겨지지 않았다.
- PyPI 측에서는 해당 패키지를 격리(quarantine) 조치하여 현재는 다운로드가 차단된 상태다. 안전한 마지막 버전은 1.82.6으로 확인됐으며, CrewAI(litellm 의존 라이브러리) 측도 이미 1.82.6으로 버전을 고정하는 커밋을 올렸다.
- 패키지 안에 악성 파일이 있음을 확인하는 방법은 간단하다. wheel 파일을 zip으로 열어 .pth 파일이 있는지 확인하거나, RECORD 파일에 litellm_init.pth 항목이 있는지 보면 된다. 정상 패키지라면 .pth 파일이 있어서는 안 된다.
- 이번 공격은 보안 연구자들이 'TeamPCP'로 추적 중인 그룹의 소행으로, 같은 그룹이 수주 전부터 Trivy 공급망을 통해 여러 프로젝트를 공격해온 것으로 파악됐다. GitHub 이슈에 봇 댓글이 170개 이상 스팸으로 달린 것도 같은 패턴이다.
Evidence
- LiteLLM 메인테이너 Krrish가 직접 댓글로 상황을 설명했다. 공격 경로는 CI/CD에서 사용하던 Trivy(오픈소스 취약점 스캐너)가 먼저 해킹당했고, 이를 통해 LiteLLM 빌드 파이프라인이 침해된 것으로 보인다는 설명이다. 보안 연구자 ramimac이 작성한 타임라인 문서(https://ramimac.me/trivy-teampcp/)에 TeamPCP 그룹의 활동이 상세히 기록되어 있다.
- CrewAI가 이미 5시간 전에 슬그머니 litellm을 1.82.6으로 고정하는 커밋을 올렸지만 커밋 메시지에 보안 관련 내용을 전혀 언급하지 않았다는 지적이 있었다. 이에 대해 사용자들 사이에서 '의존 라이브러리가 보안 이슈를 숨기는 식으로 대응하는 것은 문제가 있다'는 비판이 나왔다.
- macOS 환경을 위한 카나리아(honeypot) 탐지 도구를 만든 개발자가 자신의 오픈소스 툴(https://github.com/dweinstein/canary)을 공유했다. 가짜 시크릿 파일을 심어두고 패키지가 접근하면 알림을 받는 방식으로, '다음 공격은 CPU 과부하 같은 눈에 띄는 증상이 없을 수 있으니 이런 탐지 도구가 필요하다'는 의견이었다.
- 한 개발자는 Harbor(다른 패키지)를 설치했더니 CPU가 즉시 100%로 치솟으면서 시스템이 먹통이 됐다고 경험을 공유했다. 프로세스를 보니 `grep -r rpcuser\rpcpassword` 형태의 프로세스가 fork bomb처럼 대량으로 생성되어 암호화폐 지갑 정보를 탐색하려 했다고 한다. 빠르게 발견해서 백도어 설치 전에 막았다는 경험담이다.
- 공급망 보안 전반에 대한 논의도 활발했다. '의존성은 한 번도 믿을 수 있었던 적이 없다', 'LLM이 이 위험을 100배 증폭시켰다(스팸 패키지/악성 코드 생성이 쉬워졌으므로)', '이제는 개발 환경 자체를 에이전트 런타임처럼 샌드박스화해야 한다(egress 필터, seccomp, gVisor 등)' 같은 의견들이 나왔다. pnpm의 minimumReleaseAge처럼 새 버전을 즉시 사용하지 않고 일정 기간 후에만 허용하는 기능이 Python 생태계에도 필요하다는 제안도 있었다.
How to Apply
- 현재 litellm을 사용 중이라면 즉시 버전을 확인하고, 1.82.7 또는 1.82.8을 사용 중이면 `pip install litellm==1.82.6`으로 다운그레이드해야 한다. requirements.txt나 pyproject.toml에 `litellm==1.82.6`으로 버전을 고정(pin)해두면 재발을 방지할 수 있다.
- 혹시 해당 버전이 설치된 환경에서 Python을 실행한 적이 있다면, 해당 머신의 환경변수, SSH 키, AWS 자격증명, Kubernetes config가 유출됐을 가능성이 있다. AWS 키 로테이션, SSH 키 재생성, 쿠버네티스 서비스 어카운트 토큰 갱신을 즉시 진행해야 한다.
- 새로운 패키지를 설치할 때 .pth 파일 포함 여부를 확인하는 검증 단계를 CI/CD에 추가할 수 있다. `pip download <package> --no-deps -d /tmp/check` 후 wheel을 zip으로 열어 `.pth` 파일 존재 여부를 체크하는 스크립트를 파이프라인에 넣으면, 이런 유형의 공격을 조기에 탐지할 수 있다.
- LiteLLM을 Docker 기반으로 운영하는 경우, 공식 proxy Docker 이미지는 requirements.txt에 버전이 고정되어 있어 이번 사건의 영향을 받지 않았다. 앞으로도 중요 라이브러리는 Docker 이미지 내에서 버전을 고정하고, `pip install litellm` 처럼 최신 버전을 무조건 당기는 방식은 피하는 것이 좋다.
Code Example
# 악성 패키지 여부 확인 스크립트
pip download litellm==1.82.8 --no-deps -d /tmp/check
python3 -c "
import zipfile, os
whl = '/tmp/check/' + [f for f in os.listdir('/tmp/check') if f.endswith('.whl')][0]
with zipfile.ZipFile(whl) as z:
pth = [n for n in z.namelist() if n.endswith('.pth')]
print('PTH files:', pth) # 정상이라면 빈 리스트여야 함
for p in pth:
print(z.read(p)[:300]) # 내용 확인
"
# 안전한 버전으로 고정
pip install litellm==1.82.6
# requirements.txt에 버전 고정
# litellm==1.82.6Terminology
관련 논문
Swift로 LLM 학습시키기 Part 1: 행렬 곱셈을 Gflop/s에서 Tflop/s로 끌어올리기
Apple Silicon에서 Swift로 직접 행렬 곱셈 커널을 구현하며 CPU, SIMD, AMX, GPU(Metal)를 단계별로 최적화해 Gflop/s에서 Tflop/s 수준까지 성능을 높이는 과정을 상세히 설명한 글이다. 프레임워크 없이 LLM 학습의 핵심 연산을 밑바닥부터 구현하고 싶은 개발자에게 Apple Silicon의 성능 한계를 체감할 수 있는 드문 자료다.
fsync 없이 로컬 스토리지 엔진을 crash-consistent하게 만든 방법
FractalBits가 fsync 없이 SSD 전용 KV 스토리지 엔진을 구현해 동일 조건 대비 약 65% 높은 쓰기 성능을 달성한 설계 방법을 공유했다. fsync의 메타데이터 오버헤드를 피하기 위해 사전 할당, O_DIRECT, SSD 원자 쓰기 단위 정렬 저널을 조합한 구조가 핵심이다.
Google Chrome, 사용자 동의 없이 4GB AI 모델(Gemini Nano)을 몰래 설치
Google Chrome이 사용자 동의 없이 Gemini Nano 4GB 모델 파일을 자동 다운로드하고, 삭제해도 재다운로드되는 문제가 발견됐다. GDPR 위반 가능성과 수십억 대 기기에 적용될 때의 환경 비용 문제가 제기되고 있다.
OpenAI가 대규모 저지연 Voice AI를 제공하는 방법
OpenAI가 9억 명 이상의 사용자에게 실시간 음성 AI를 제공하기 위해 WebRTC 스택을 어떻게 재설계했는지 설명하는 글로, relay + transceiver 분리 아키텍처의 설계 결정과 trade-off를 상세히 다룬다.
Truncated Decoding Tree의 결정론적 탐색을 통한 효율적인 Test-Time Inference
Self-consistency의 중복 샘플링 낭비를 없애는 결정론적 트리 탐색 디코딩 기법 DLE로 수학/코드 추론 성능과 속도를 동시에 개선
GoModel – Go로 작성된 오픈소스 AI Gateway
OpenAI, Anthropic, Gemini 등 여러 AI 프로바이더를 하나의 OpenAI 호환 API로 묶어주는 Go 기반 오픈소스 AI 게이트웨이로, LiteLLM의 컴파일 언어 대안이다.