LiteLLM 사고는 어떻게 시작됐나
PyPI에 악성 버전 1.82.7과 1.82.8이 올라온 뒤 드러난 것들, 그리고 왜 이 사건이 AI 개발 생태계 전체의 문제로 읽혔는지
LiteLLM 사고는 어떻게 시작됐나
PyPI에 악성 버전 1.82.7과 1.82.8이 올라온 뒤 드러난 것들, 그리고 왜 이 사건이 AI 개발 생태계 전체의 문제로 읽혔는지
Olga Guryanova
2026년 3월 24일, Hacker News에는 LiteLLM에 대한 짧고 급한 경고가 올라왔다. 글쓴이는 새 프로젝트를 준비하던 중 노트북 메모리 사용량이 갑자기 치솟았고, 이상한 Python 프로세스가 연쇄적으로 실행되는 현상을 봤다고 적었다. 처음에는 단순한 버그처럼 보였지만, 몇 시간 안에 상황은 다른 방향으로 정리되기 시작했다. 그날 PyPI에 올라온 LiteLLM 일부 버전이 악성 코드가 포함된 상태였다는 분석이 공개된 것이다.
이 사건이 많은 사람에게 충격적으로 다가온 이유는 출발점이 낯설지 않았기 때문이다. 의심스러운 첨부파일을 연 것도 아니고, 수상한 링크를 누른 것도 아니었다. 평소처럼 Python 패키지를 설치하고, 평소처럼 개발 환경을 실행하는 과정에서 문제가 시작됐다. 그만큼 이번 사건은 단일 패키지 문제를 넘어, 지금의 개발 환경이 어떤 배포 경로와 계정 체계 위에서 돌아가는지를 함께 돌아보게 했다.
LiteLLM은 여러 AI 모델을 하나의 인터페이스로 연결해 주는 오픈소스 도구다. PyPI와 GitHub 설명을 기준으로 보면, 이 프로젝트는 단순한 Python 라이브러리라기보다 두 층으로 이해하는 편이 맞다. 하나는 개발자가 애플리케이션 코드 안에서 직접 쓰는 Python SDK이고, 다른 하나는 여러 팀이 공통으로 붙을 수 있는 Proxy Server, 즉 AI Gateway다. 프로젝트 설명이 강조하는 핵심도 여기에 있다. OpenAI, Anthropic, Azure, Vertex AI, Bedrock 같은 서로 다른 제공자의 모델을 OpenAI format에 가깝게 통일된 방식으로 호출하게 해 주고, 여기에 라우팅, 재시도, 로드밸런싱, 비용 추적, 로깅 같은 운영 기능을 얹는다.
그래서 LiteLLM은 “모델을 한 번 더 감싸는 편의 라이브러리” 정도로만 보기는 어렵다. 개인 개발자가 코드에서 바로 호출할 수도 있지만, 팀 단위로는 여러 모델 공급자와 키를 중앙에서 관리하는 게이트웨이처럼 쓰이기도 한다. PyPI 프로젝트 페이지도 LiteLLM을 Python SDK + AI Gateway로 설명하고 있고, 100개가 넘는 LLM API를 지원한다고 소개한다. 다시 말해, 문제가 된 것은 낯선 실험용 패키지가 아니라 이미 AI 애플리케이션 개발과 운영 흐름에 깊게 들어와 있던 도구였다.
정량 지표를 봐도 비슷한 그림이 나온다. 글 작성 기준 (2026–03–25 기준) GitHub 저장소는 약 40.4k 스타와 6.7k 포크를 기록하고 있었고, 저장소 히스토리에는 36,173개의 커밋이 표시된다. PyPI 자체는 다운로드 수를 직접 노출하지 않지만, PyPI 다운로드 통계를 별도로 집계하는 PyPI Stats 기준으로 litellm은 최근 하루 3,455,068, 최근 일주일 21,590,934, 최근 한 달 96,083,740 다운로드를 기록하고 있었다. 물론 다운로드 수는 실제 사용자 수와 일치하지 않는다. CI, 캐시, 자동화된 배포도 숫자에 포함될 수 있다. 그래도 이 정도 지표면 LiteLLM이 작은 실험 프로젝트가 아니라, 이미 광범위하게 소비되고 있던 패키지였다는 점은 분명해 보인다.
공개된 LiteLLM 팀 업데이트에 따르면, 영향을 받은 버전은 1.82.7과 1.82.8이었다. 팀은 공격자가 유지보수자의 PyPI 계정에 접근한 뒤 악성 버전을 PyPI에 직접 게시했다고 설명했다. 이 배포는 공식 GitHub 릴리스 흐름과는 별도로 이뤄졌고, 사건이 확인된 뒤 두 버전은 삭제됐다. 같은 날 공개된 추가 설명에서 LiteLLM 팀은 유지보수 계정을 교체했고, 조사 범위를 넓히기 위해 Google의 Mandiant 팀과도 협력하고 있다고 밝혔다.
보안 업체들이 공개한 후속 분석은 시간대도 더 촘촘하게 복원했다. Snyk는 1.82.7이 2026년 3월 24일 10:39 UTC, 1.82.8이 10:52 UTC에 올라왔고, PyPI 격리는 대략 13:38 UTC 전후 이뤄졌다고 정리했다. 이 계산을 따르면 악성 버전이 공개 저장소에서 내려받을 수 있었던 시간은 약 세 시간이다. 이 시간표는 LiteLLM 팀의 공식 타임라인이라기보다 보안 업체가 공개 증거를 바탕으로 재구성한 내용이지만, 사건의 속도를 이해하는 데는 도움이 된다.
이번 사건에서 특히 주목받은 쪽은 1.82.8이었다. 공개 이슈에 첨부된 분석에 따르면, 이 버전에는 litellm_init.pth라는 파일이 포함돼 있었다. .pth 파일은 Python이 시작될 때 읽을 수 있는 파일이다. Python 공식 문서도 특정 .pth 파일 안의 코드가 인터프리터 시작 과정에서 실행될 수 있다고 설명한다. 비개발자 입장에서 더 쉽게 말하면, 사용자가 LiteLLM을 직접 실행하지 않아도 같은 환경에서 Python을 시작하는 것만으로도 악성 코드가 작동할 수 있었다는 뜻이다.
1.82.7도 안전했던 것은 아니다. LiteLLM 팀 업데이트는 1.82.7이 import litellm.proxy 경로를 통해 악성 동작을 일으켰다고 설명한다. 다만 1.82.8은 Python 시작 시점에 더 넓게 작동할 수 있었기 때문에, 공개된 분석과 커뮤니티 반응에서 더 위험한 버전으로 받아들여졌다. 이 차이는 사건을 이해하는 데 중요하다. 같은 패키지 이름 아래 배포됐더라도, 두 버전의 작동 방식과 노출 범위는 같지 않았기 때문이다.
그렇다면 악성 코드는 무엇을 노렸을까. 공개된 기술 분석과 LiteLLM 팀 업데이트가 공통으로 가리키는 대상은 개발 환경에 이미 저장돼 있는 민감한 정보였다. 환경 변수, SSH 키, 클라우드 자격 증명, Kubernetes 설정, 셸 기록, 각종 설정 파일이 수집 대상에 포함됐다. 외부 전송 목적지로 지목된 주소는 models.litellm.cloud였다. 공개된 자료 기준으로 보면, 이번 배포본은 개발자 환경의 자격 증명과 설정 정보를 수집해 외부로 전송하도록 설계돼 있었다.
FutureSearch가 공개한 발견 경위도 사건을 이해하는 데 도움이 된다. 이 설명에 따르면 문제의 패키지는 Cursor 안에서 동작하던 MCP 플러그인의 전이 의존성으로 설치됐다. 이후 .pth 파일이 Python 시작 시 자동 실행되면서 새 Python 프로세스를 다시 띄웠고, 그 프로세스가 다시 같은 .pth를 실행하는 방식으로 메모리 고갈이 발생했다. FutureSearch는 이를 악성코드의 의도된 기능이 아니라 구현상의 버그에 가까운 현상으로 설명했다. 이 때문에 사건은 정교한 탐지 시스템보다 먼저, 개발자가 체감한 이상 동작을 통해 드러났다.
다만 여기서 한 가지는 분명히 구분할 필요가 있다. 공개된 정보만으로는 전체 피해 범위가 아직 완전히 확정되지 않았다. 실제로 Hacker News에 올라온 LiteLLM 유지보수자 답변에는 “blast radius”, 즉 영향 범위를 계속 조사하고 있다는 표현이 나온다. 그래서 지금 단계에서 정확하게 말할 수 있는 것은 “어떤 동작이 악성으로 설계됐는지”이지, “정확히 몇 명이 어떤 피해를 입었는지”까지는 아니다. 기사에서도 이 차이를 분리해서 적는 편이 정확하다.
영향권에 대한 설명도 같은 원칙으로 봐야 한다. LiteLLM 유지보수자는 공식 Proxy Docker 이미지 사용자는 영향을 받지 않았다고 밝혔다. 그 경로에서는 의존성 버전이 고정돼 있었기 때문이다. 반대로 점검 대상이 되는 것은 사건 당일 1.82.7 또는 1.82.8을 직접 설치했거나, 버전이 고정되지 않은 경로를 통해 같은 배포본을 받아 갔을 가능성이 있는 환경이다. 여기서 중요한 것은 "LiteLLM을 썼는가"보다 "어떤 방식으로 설치했는가"다.
이 대목은 이번 사건을 다른 보안 사고와 구분해 준다. 많은 사람은 보안 사고를 여전히 피싱 메일, 악성 문서, 의심스러운 실행 파일과 연결해 생각한다. 하지만 이번 일은 평소와 다른 행동보다, 오히려 너무 평소 같은 행동에서 시작됐다. Python 생태계의 공식 패키지 저장소인 PyPI에서 패키지를 내려받고, 개발 환경에서 Python을 실행하는 과정이 문제의 출발점이었다. 낯선 행위가 아니라 익숙한 행위가 경고 신호를 가렸다는 점에서, 이 사건은 더 널리 회자됐다.
실제로 이 사건은 개발자 커뮤니티 안에서 빠르게 확산됐다. LiteLLM 팀 이슈와 Hacker News 토론뿐 아니라, 여러 보안 연구자와 업계 인사들도 관련 내용을 공유했다. Andrej Karpathy가 X에 관련 글을 올린 것도 그 흐름 중 하나였다. 다만 이런 반응은 사건의 중요도를 보여주는 주변 맥락일 뿐, 사실관계의 핵심 근거는 여전히 LiteLLM 팀이 공개한 업데이트와 악성 패키지 분석 이슈, 그리고 Python 문서 같은 1차 자료에 두는 편이 정확하다.
이번 사건을 둘러싸고는 추가 분석도 이어졌다. SafeDep 같은 보안 업체와 FutureSearch 같은 연구 그룹은 악성 패키지의 동작 방식과 발견 경위를 더 자세히 정리했다. 이런 분석은 사건을 이해하는 데 도움을 주지만, 동시에 어디까지가 공식 확인이고 어디까지가 공개 분석인지를 구분해서 읽어야 한다. 특히 전체 피해 규모나 추가 행위에 대한 해석은 아직 조사 중인 부분이 남아 있다. 기사에서 이 선을 넘기 시작하면 글은 쉽게 단정적으로 보이게 된다.
그래도 보안 리서치가 보강해 주는 팩트는 분명히 있다. SafeDep와 Snyk는 모두 이 악성 배포본을 수집 -> 암호화 및 외부 전송 -> 지속성 확보의 다단계 구조로 설명한다. SafeDep는 litellm_init.pth의 크기를 34,628바이트로 적시했고, 악성 휠의 SHA256, 로컬 지속성 경로 ~/.config/sysmon/sysmon.py, 사용자 systemd 유닛 ~/.config/systemd/user/sysmon.service, kube-system 네임스페이스의 node-setup-* 포드 같은 탐지 지표도 공개했다. 이런 세부 지표는 LiteLLM 공식 공지보다 훨씬 기술적이지만, 기사 말미의 참고 자료로는 충분한 가치가 있다.
또 하나 눈에 띄는 대목은 인프라 흔적이다. LiteLLM 팀 이슈와 SafeDep, Snyk 분석은 모두 외부 전송 목적지로 models.litellm.cloud를 지목한다. LiteLLM 팀 이슈에는 이 도메인이 2026년 3월 23일에 등록됐다는 내용이 담겨 있고, Snyk와 SafeDep도 같은 날짜를 적고 있다. 프로젝트의 공식 도메인은 litellm.ai이기 때문에, 이 주소는 정상 인프라가 아니라 공격 인프라를 구분하는 핵심 단서로 읽힌다.
사건 타임라인
2026-03-23: LiteLLM 팀 이슈와 Snyk, SafeDep 분석은 공격 인프라로 지목된models.litellm.cloud도메인이 이날 등록됐다고 적고 있다.2026-03-24 10:39 UTC(19:39 KST): Snyk 기준으로 악성litellm==1.82.7이 PyPI에 게시됐다.2026-03-24 10:52 UTC(19:52 KST): 악성litellm==1.82.8이 PyPI에 올라왔다. 공개 분석 기준으로는 이 버전부터.pth파일을 통해 Python 시작 시 자동 실행이 가능했다.2026-03-24 11:48 UTC(20:48 KST): GitHub 이슈 #24512가 열리며 기술 분석이 공개되기 시작했다.2026-03-24 12:36 UTC(21:36 KST): Hacker News incident thread가 올라오며 커뮤니티 경고가 빠르게 확산됐다.2026-03-2413:38 UTC전후 (22:38 KST전후): Snyk 기준으로 PyPI 격리가 이뤄졌다. 이 계산을 따르면 악성 버전이 공개 저장소에서 내려받을 수 있었던 시간은 약 세 시간이다.2026-03-24 13:48 UTC(22:48 KST): GitHub 이슈 #24518가 열리며 LiteLLM 팀의 공식 타임라인과 상태 업데이트가 정리되기 시작했다.2026-03-24늦은 시간: LiteLLM 유지보수자는 계정과 키를 교체했고, 문제 버전 삭제와 추가 조사에 들어갔다고 밝혔다. Hacker News와 GitHub 업데이트에는 GitHub, Docker, CircleCI, PyPI 관련 키를 삭제하거나 교체했다는 설명이 담겼다.2026-03-25: PyPI의 LiteLLM 페이지에서는 문제 버전1.82.7,1.82.8이 보이지 않았고, 공개된 정상 버전은1.82.6까지 확인됐다.
2026년 3월 25일 기준으로 PyPI의 LiteLLM 페이지에서 확인되는 공개 버전은 1.82.6까지다. 문제가 된 1.82.7과 1.82.8은 더 이상 보이지 않는다. 사건 공개 직후 필요한 차단과 계정 교체 조치는 빠르게 이뤄졌지만, 공개된 흐름만 봐도 남은 과제는 분명하다. 어떤 계정과 게시 경로가 공격자에게 넘어갔는지, 어떤 자격 증명이 노출됐는지, 어떤 설치 경로가 실제 영향을 받았는지 같은 문제는 이후 조사에서 더 구체적으로 확인돼야 한다.
현재까지 공개된 사실만으로도 사건의 윤곽은 비교적 명확하다. 2026년 3월 24일, 널리 쓰이던 AI 개발 도구 LiteLLM의 PyPI 배포본 일부가 악성 코드가 포함된 상태로 게시됐다. 그 코드는 개발자 환경의 민감한 정보를 수집해 외부로 전송하도록 설계돼 있었고, 특히 1.82.8은 Python 시작 과정에서 작동할 수 있었다. LiteLLM 팀은 문제 버전을 삭제하고 계정과 키를 교체했으며, 공식 Proxy Docker 이미지 사용자는 영향을 받지 않았다고 밝혔다. 나머지 범위는 여전히 조사 중이다.
참고 자료
- LiteLLM 팀 타임라인 및 상태 업데이트: https://github.com/BerriAI/litellm/issues/24518
- 악성
.pth파일 분석 이슈: https://github.com/BerriAI/litellm/issues/24512 - Python
site및.pth동작 문서: https://docs.python.org/3/library/site.html - Hacker News incident thread, first user report, and maintainer comments: https://news.ycombinator.com/item?id=47501426
- PyPI LiteLLM 페이지: https://pypi.org/project/litellm/
- PyPI Stats의
litellm다운로드 통계: https://pypistats.org/packages/litellm - FutureSearch의 첫 공개 분석: https://futuresearch.ai/blog/litellm-pypi-supply-chain-attack/
- SafeDep의 악성 패키지 분석: https://safedep.io/malicious-litellm-1-82-8-analysis/
- Snyk의 사고 분석 기사: https://snyk.io/articles/poisoned-security-scanner-backdooring-litellm/
- Snyk 취약점 DB 항목: https://security.snyk.io/vuln/SNYK-PYTHON-LITELLM-15762713
- 참고: https://x.com/karpathy/status/2036487306585268612
메타데이터
- post_id
- e44b37549b87
- slug
- litellm-사고는-어떻게-시작됐나-e44b37549b87
- url
- https://medium.com/@aristojeff/litellm-%EC%82%AC%EA%B3%A0%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%8B%9C%EC%9E%91%EB%90%90%EB%82%98-e44b37549b87
- canonical_url
- https://medium.com/@aristojeff/litellm-%EC%82%AC%EA%B3%A0%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%8B%9C%EC%9E%91%EB%90%90%EB%82%98-e44b37549b87
- author_url
- https://medium.com/@aristojeff
- status
- ok
- fetched_at
- 2026-08-22 05:45:58