LiteLLM 악성 버전, 공식 태그엔 없던 파일

파이썬으로 AI 앱을 만들면서 pip install litellm을 버전 지정 없이 쓰는 사람이라면, 한국 시각으로 2026년 10월 21일 저녁 8시 39분부터 10시 23분 사이에 설치한 적이 있는지부터 떠올려야 한다. 그 시간 동안 PyPI(파이썬 패키지를 모아 둔 공식 저장소)에 올라 있던 LiteLLM 1.107.0에 비밀번호와 키를 훔치는 코드가 들어 있었다.
이 사고에서 제일 이상한 점은 깃허브 쪽이다. 1.107.0의 공식 태그(릴리스 지점을 가리키는 이름표)에는 악성 파일이 하나도 없다. 회사 글도 그렇게 적었다. 그런데 PyPI에 올라간 설치 파일에는 파일 세 개가 더 들어 있었다. 코드는 멀쩡해 보이고 배포물만 달랐다는 뜻이다. 어떻게 그럴 수 있었는지, 내가 LiteLLM 악성 버전에 해당되는지, 해당되면 무엇을 어떤 순서로 해야 하는지가 이 글의 내용이다.
LiteLLM은 오픈AI·앤스로픽·구글 같은 여러 회사의 AI 모델을 한 가지 방식으로 부르게 해 주는 오픈소스 도구다. 파이썬 라이브러리로 쓰기도 하고, 프록시 서버(팀 전체의 요청을 받아 각 모델 회사에 대신 전달하는 서버)로 띄우기도 한다. 프록시는 모델 회사들의 API 키를 자기 데이터베이스에 보관한다. 그래서 이 도구가 뚫리면 피해가 “내 키 하나”에서 끝나지 않는다.
근거로 삼은 자료는 다섯 가지다. 회사가 올린 사고 공지(docs.litellm.ai), 보안 업체 업윈드(Upwind)가 깃허브 이슈 #47826에 올린 보고와 회사 직원들의 답글, 보안 업체 세이프디프(SafeDep)와 위즈(Wiz)의 분석 글, 깃허브·PyPI·도커 허브의 공개 조회 결과, 해커뉴스 토론이다. 직접 해 본 일은 일곱 가지이고 마지막 절에 모았다. 그 밖의 사실은 전부 각 자료가 적은 내용이며, 누구 말인지 문장마다 밝혔다.
한국 시각으로 읽는 하루: 저녁 8시 39분에 올라와 10시 23분에 내려갔다
회사 공지와 위즈 글의 시각(UTC)을 한국 시각으로 바꿔 한 표에 놓았다. 모두 10월 21일 기준이고, 괄호 안은 근거다.
| 한국 시각 | 일어난 일 |
|---|---|
| 오후 5시 56분 | 공격자가 비슷한 이름의 저장소 Berri-AI/litellm에 첫 커밋(내가 깃허브 비교 조회로 확인) |
| 저녁 7시 8분 | 회사의 비공개 릴리스 워크플로 수정이 보호 규칙에 한 번 막혔다가, 5초 뒤 권한 높은 개발자 계정의 자격증명으로 보호가 풀려 반영됨(회사 글) |
| 저녁 8시 8분 | 정식 릴리스 절차 시작. 3분 뒤 두 번째 개발자 계정이 승인 단계를 통과(회사 글) |
| 저녁 8시 39분 | PyPI에 악성 wheel(설치용 묶음 파일) 7개 업로드 |
| 저녁 8시 46분 | 도커 이미지 v1.107.0, latest, main-latest, main-stable 게시 |
| 저녁 8시 53분 | 세 번째 개발자 계정으로 워크플로 실행 기록 삭제(회사 글) |
| 밤 9시 6분 | 업윈드 연구팀이 깃허브에 신고 |
| 밤 10시 23분 | PyPI에서 1.107.0 제거 |
| 밤 10시 51분 | GHCR(깃허브의 도커 이미지 저장소) 태그 접근 불가 확인 |
| 밤 11시 20분 | 도커 허브 태그 전부 제거되거나 안전한 쪽으로 되돌림 |
PyPI에 올라 있던 시간은 1시간 43분이다. 회사 글은 “약 2시간”이라고 적었는데 시각을 빼 보면 그렇다. 도커 허브는 2시간 33분, GHCR은 2시간 4분 안쪽이다. 신고에서 PyPI 제거까지는 77분이 걸렸다.
길다고 보기도 짧다고 보기도 어렵다. 다만 새로 만드는 서버와 자동 빌드(CI)는 사람이 보지 않는 사이에 최신 버전을 알아서 받아 가니, 몇 분만 열려 있어도 충분하다. 3월에 비슷한 일이 한 번 있었다는 점은 뒤에서 다룬다.
태그에는 없고 PyPI 파일에만 있던 세 파일
악성 wheel 일곱 개에는 같은 파일 세 개가 site-packages(파이썬이 설치된 패키지를 두는 폴더) 맨 위에 풀린다. 업윈드 보고와 위즈 글이 적은 크기는 아래와 같다.
| 파일 | 크기 | 하는 일 |
|---|---|---|
cook.pth |
12바이트 | import cook 한 줄. 파이썬이 켜질 때마다 cook.py를 불러온다 |
cook.py |
22,252바이트 | 압축·인코딩으로 감싼 비밀 수집기. 업윈드는 내부 이름이 privcollect라고 적었다 |
sitecustomize.py |
25,509바이트 | 백그라운드 프로그램을 띄워 매시간 원격에서 받은 코드를 실행 |
여기서 핵심은 .pth 파일이다. 파이썬은 시작할 때 site-packages 안의 .pth 파일을 읽는데, 줄이 import로 시작하면 그 줄을 그대로 실행한다. 원래는 패키지 경로를 등록하려고 만든 장치다. 그래서 LiteLLM을 한 번도 불러오지 않는 프로그램, 심지어 pip 자체도 파이썬이 켜지는 순간 이 코드를 돌린다. 업윈드 보고가 “영향받은 환경에서는 pip install부터 치지 말라”고 한 이유다.
어떻게 태그에 없는 파일이 wheel에는 들어갔을까. 세이프디프 글에 따르면 소스 배포 파일의 설정 파일(pyproject.toml)에 한 줄이 더 있었다. data = "cook"이라는 줄이다. 이 줄이 있으면 빌드 도구(maturin)가 cook/ 폴더를 wheel 안에 같이 넣는다. 소스 배포 파일에는 cook/ 폴더가 빠져 있어서, 겉으로 보이는 흔적은 그 한 줄뿐이었다.
회사 글이 설명한 결론도 같다. 악성 파일은 공식 저장소가 아니라 공격자가 통제하는 저장소에서 빌드된 결과물이었다.
해롭지 않은 한 줄로 같은 길을 재 봤다
“파이썬이 켜질 때마다”가 정말 그런지 직접 해 보았다. 임시 가상환경(venv)에 demo.pth를 만들고 안에 import demo_hello 한 줄을 넣었다. demo_hello.py는 화면에 문장 하나를 찍을 뿐이다. 악의가 없는 같은 구조다.
| 실행한 명령 | 결과 |
|---|---|
python -c 'print("main")' |
데모 문장이 먼저 찍힌 뒤 main |
pip --version |
데모 문장이 먼저 찍힘 |
python -I -c ... (격리 모드) |
데모 문장이 찍힘 |
python -S -c ... (site 모듈을 건너뜀) |
데모 문장이 안 찍힘 |
격리 모드(-I)가 막아 줄 거라고 짐작하기 쉬운데, 이 맥의 파이썬 3.14.6에서는 막지 못했다. .pth를 건너뛴 것은 -S뿐이었다. 다만 -S는 site 모듈을 통째로 끄는 옵션이라 평소 실행에는 쓸 수 없다.
하나 더 있다. 같은 가상환경의 site-packages에 sitecustomize.py도 놓아 봤는데, 실행되지 않았다. 이 맥의 홈브루 파이썬은 표준 라이브러리 폴더에 자기 sitecustomize.py를 이미 두고 있어서 먼저 그쪽이 불려 갔다(sitecustomize.__file__로 경로 확인). 그러니 이 환경에서라면 악성 sitecustomize.py의 매시간 원격 실행 쪽은 가려졌을 것이다. 하지만 cook.pth는 그대로 돌고, 훔치는 일은 그쪽이 한다. 도커 이미지나 다른 배포판은 사정이 다를 수 있어서 “나는 홈브루라 괜찮다”는 결론은 낼 수 없다.
훔쳐 가는 것은 키 하나가 아니라 컴퓨터에 놓인 거의 전부다
업윈드가 풀어 읽은 cook.py는 모듈 16개로 나뉜다. 대상은 이렇다.
- 브라우저에 저장된 비밀번호와 기록(크롬 계열, 파이어폭스)
~/.ssh아래 키, 셸 명령 기록- AWS·애저·구글 클라우드·쿠버네티스·도커·깃허브 CLI·rclone 자격증명
.env파일,.pem·.key파일,.npmrc,.pypirc같은 패키지 도구 설정- 클로드, 코덱스, 제미나이, 커서, 윈드서프, VS Code MCP 설정 같은 AI 도구의 로그인 정보
- 읽을 수 있는 모든 프로세스의 환경변수(
/proc/*/environ) - 서버라면 클라우드 메타데이터에서 받는 역할(IAM role) 자격증명
DATABASE_URL이 있으면 LiteLLM 프록시 데이터베이스의LiteLLM_CredentialsTable과LiteLLM_ProxyModelTable을 통째로 덤프. 이 표에 프록시가 보관한 모델 회사 키 전부가 있다
수집한 내용은 AES-256 방식으로 암호화하고 그 열쇠를 다시 RSA-4096 공개키로 감싸 www.litellm[.]dev/healthcheck로 보낸다. 네트워크 기록만 봐서는 내용을 풀 수 없다는 뜻이다. 이 도메인은 프로젝트의 진짜 도메인(litellm.ai)이 아니며, 업윈드에 따르면 10월 13일에 등록됐다. 사고 8일 전이다.
sitecustomize.py가 띄우는 백그라운드 프로그램은 한 시간마다 깃허브 사용자 letters9813의 저장소 파일에서 서버 주소를 읽고, 그 서버가 내려 주는 코드를 실행한다. 이 계정도 10월 13일에 만들어졌다. 위즈는 이 파일이 시험값 외에는 채워진 적이 없다고 적었고, 세이프디프는 서버 주소를 끝내 복구하지 못했다고 적었다. 그 저장소는 사고 당일 한국 시각 밤 10시 30~40분쯤 사라졌다. 그러니 두 번째 단계 코드가 실제로 내려갔다는 증거는 없다. 하지만 “없다”는 것과 “확인했다”는 다르다. 첫 번째 단계(훔치기)만으로도 교체할 것은 충분히 많다.
공식 릴리스 파이프라인이 비슷한 이름의 저장소를 읽었다
가장 불쾌한 대목이다. 공격자는 회사의 공식 릴리스 과정을 우회하지 않고, 그 과정을 직접 돌렸다. 회사 글이 적은 경과는 이렇다.
- 3월 사고 뒤 회사는 릴리스를 비공개 저장소로 옮기고, 신뢰 게시자(Trusted Publisher, PyPI가 특정 워크플로만 올리도록 묶는 방식)를 쓰고, 도커 태그를 고정하고, 이미지에 서명을 붙였다. 게시는 사무실 안의 특정 노트북에 묶인 계정만 할 수 있다고 한다.
- 월요일(10월 19일)에 회사는 고객용 수정본을 매일 내려고 엔지니어 두 명에게 릴리스 권한을 임시로 넓혔다.
- 공격자는 개발자 세 명의 깃허브 CLI 자격증명을 손에 넣었다. 그중 하나는 조직 소유자 두 명 가운데 한 사람 것이었다. 처음에 릴리스 워크플로를 다른 소스 저장소로 돌릴 수 있게 하는 변경을 병합하려 했지만 보호 규칙에 막혔고, 소유자 권한으로 보호 규칙을 끄고 강제로 밀어 넣었다.
- 그 워크플로를
BerriAI/litellm이 아니라 하이픈 하나가 더 붙은Berri-AI/litellm에서 소스를 읽도록 돌렸다. 정식 파이프라인은 서명하고 게시했다.
내가 깃허브 공개 조회로 확인한 것이 있다. 비교 주소 compare/a8113b0d...20535d8f를 부르면 커밋 10개가 나온다. 시작은 오후 5시 56분 59초, 끝은 저녁 7시 46분 29초(한국 시각)다. 아홉 개는 같은 메일 주소로 올라왔고 마지막 하나만 다른 주소다. 처음 세 개는 1분 45초 안에 연달아 올라왔고 메시지가 “Add import statement”, “Change greeting”, “Add” 다. 그 뒤로는 버전을 1.107.0으로 맞추는 평범한 chore: 커밋들이 이어지고, 마지막 커밋이 도커 빌드 파일에 COPY cook ./cook을 더한다. 바꾼 파일 10개 중 cook.pth와 cook.py는 각각 한 줄이다. 눈에 띄지 않게 만든 흔적이다.
저장소 자체(Berri-AI/litellm)는 지금 조회하면 404가 나온다. 그런데 커밋은 원래 저장소의 포크 관계 덕에 비교 주소로 그대로 열린다. 위즈가 “저장소는 안 보이지만 모든 커밋이 부모 저장소를 통해 접근 가능하다”고 적은 그대로다.
한 가지 더. 위즈는 페이로드에 LLM의 도움을 받은 흔적이 있다고 평가했다. 변수 이름이 장황하고, 예외 처리가 과하게 방어적이며, 윈도에서는 조용히 실패하는 경로가 있고, 정의만 하고 부르지 않는 모듈이 있다는 근거를 들었다. 이는 위즈의 해석이고, 누가 어떤 도구로 썼는지는 확인된 바 없다.
토큰은 어디서 새어 나갔나: 회사의 추정과 아직 비어 있는 곳
개발자 세 명의 자격증명이 어떻게 공격자 손에 들어갔는지는 아직 확정되지 않았다. 회사가 10월 22일 한국 시각 오전 5시 30분(UTC 20:30)에 갱신한 사고 공지에 적은 추정은 이렇다.
- 회사의 내부 LiteLLM 배포에 낯선 이름의 사용자 계정이 있었다. 이 배포는 공개 인터넷에 열려 있었다.
- 공격자가 이 배포에 들어가 로그에서 깃허브 CLI OAuth 토큰을 얻은 것 같다. 어떻게 들어갔는지는 모르며, 최근 패치된 취약점일 것으로 의심한다.
- 회사 글은 “특정 상황에서 클로드 코드가 사용자의 깃허브 CLI OAuth 토큰을 응답 본문에 넣는 것을 관찰했고, 응답 본문을 로그로 남기는 경우 그 토큰이 LiteLLM 로그에 나타날 수 있다”고 적었다.
세 번째 문장은 클로드 코드를 쓰는 사람에게 무겁게 들린다. 다만 이 글을 쓰는 시점에 앤스로픽 쪽의 확인이나 독립 재현을 찾지 못했고, 회사 스스로도 “아직 확인 중”이라고 적었다. 그러니 지금은 “회사가 그렇게 추정한다” 이상으로 읽으면 안 된다. 읽을 만한 일반론은 있다. AI 게이트웨이가 요청과 응답 본문을 통째로 기록한다면, 그 기록에는 사람이 붙여 넣은 비밀 값이 섞여 들어갈 수 있다. 로그 보관 설정과 접근 권한을 오늘 한 번 보는 값어치가 있다.
훔친 키는 4시간 반 만에 쓰이기 시작했다
위즈는 훔친 자격증명이 실제로 쓰이는 것을 봤다고 적었다. 유출 후 약 4시간 반이 지난 10월 22일 새벽 1시 20분부터 2시 1분(한국 시각) 사이에, 공격자는 서로 다른 두 주소에서 AWS 인스턴스 역할 자격증명 여러 개를 유효한지 확인했다. GetCallerIdentity라는 신원 확인 호출로 확인한 뒤, 베드록(AWS의 AI 모델 서비스)의 모델 목록을 조회하는 호출을 이어서 불렀다. 위즈는 이 순서를 남의 계정으로 AI를 돌려 쓰는 LLM재킹에 맞는 행동이라고 봤다. 일부 환경에서는 사용자·역할 목록 조회로 번졌다.
이 순서는 업윈드가 “클라우드 로그에서 GetCallerIdentity 호출을 찾아보라”고 한 점검 항목과 맞물린다. 설치 시각 즈음에 서버의 역할 자격증명으로 신원 확인이 나갔는지, 그 뒤 우리 인프라 밖 주소에서 같은 자격증명이 쓰였는지가 피해 여부를 가른다.
LiteLLM 악성 버전에 해당되는지 가리는 두 가지 조건
회사 공지가 정한 영향 조건은 둘 중 하나다.
- pip: 버전을 고정하지 않은 상태에서 한국 시각 10월 21일 저녁 8시 39분~밤 10시 23분에
litellm을 설치하거나 업그레이드했다. - 도커: 같은 날 저녁 8시 46분~밤 11시 20분에
v1.107.0,latest,main-latest,main-stable중 하나를 받아 실행했다.
확인은 이렇게 한다. pip show litellm이 1.107.0을 보여 주거나, site-packages에 litellm-1.107.0.dist-info 폴더나 cook.pth·cook.py가 있으면 해당한다. sitecustomize.py는 정상적으로 쓰는 환경도 있으니 크기가 25,509바이트인지 함께 본다. 서버가 도커라면 실행 중인 이미지 해시가 sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e(도커 허브의 악성 이미지 인덱스)인지 본다.
없다고 안심하면 안 된다. 회사 글도 업윈드 보고도 같은 말을 한다. 컨테이너를 지웠거나 /tmp를 청소했다면 흔적이 사라지고, 흔적이 없다는 것이 훔치지 않았다는 증거가 못 된다. 다음 흔적은 남아 있으면 감염의 증거가 된다.
/tmp/.pc_once_72129118c59f5636c0bb: 수집 결과를 전송한 뒤에만 만들어지는 표식/tmp/remote_code_loader.lock: 백그라운드 프로그램이 한 번이라도 돈 흔적- 환경변수
PRIVCOLLECT_ACTIVE=1 - 부모가 PID 1이고 작업 폴더가
/인 파이썬 프로세스
나는 이 맥에서 mdfind로 cook.pth를 찾아봤고 없었다. 시스템 파이썬에 litellm은 설치돼 있지 않았고, 이 맥의 파이썬이 읽는 .pth 중 import로 시작하는 줄이 있는 것은 0개였다. 이 확인은 이 맥에 대한 것일 뿐이다.
해당된다면: pip부터 치지 말고 이 순서로
업윈드 보고와 회사 공지의 순서를 합치면 이렇다.
- 셸에서 직접
cook.pth,cook.py,sitecustomize.py를 지운다. 연관된__pycache__/cook*.pyc,sitecustomize*.pyc도 지운다. 영향받은 모든site-packages에서.pip도 파이썬이라서, 이걸 지우기 전에pip를 부르면 코드가 또 돈다. /tmp/remote_code_loader.lock을 쥔 백그라운드 파이썬 프로세스를 종료한다.litellm==1.106.2로 다시 설치한다. 가능하면 가상환경과 이미지를 처음부터 다시 만든다.- 바깥으로 나가는 통신이 가능한 호스트에 1.107.0이 한 번이라도 깔렸다면 유출됐다고 가정한다.
- 그 컴퓨터가 닿을 수 있던 비밀을 모두 교체한다.
- 서버의 IAM 역할 자격증명
- LiteLLM 프록시 데이터베이스에 있는 모든 모델 회사 키, 마스터 키, 가상 키
DATABASE_URL의 비밀번호- 그 호스트 프로세스의 환경변수에 있던 모든 비밀 값
- SSH 키, 깃허브·클라우드 토큰,
.env, AI 도구(클로드 코드·코덱스·커서 등) 로그인
- 클라우드 로그에서 설치 시각 즈음의
GetCallerIdentity와, 그 뒤 우리 인프라 밖에서 쓰인 역할 자격증명을 찾는다.
모델 회사 키를 바꾼 뒤에는 지출 한도도 같이 건다. 키가 새도 하루 피해액에 상한이 있으면 사고가 작아진다. 서비스별로 어디서 거는지는 오픈코드 해킹 때 정리한 글에 정리해 두었다.
해당되지 않아도 오늘 바꿀 세 가지: 고정, 해시, 쿨다운
이번에 피한 사람은 운이 좋았거나 이미 고정해 둔 사람이다. 고정하지 않은 사람은 다음 번에 같은 시간대에 걸릴 수 있다.
첫째, 버전을 정확히 고정한다. litellm==1.106.2처럼 쓴다. 도커는 latest가 아니라 해시(다이제스트) 로 부른다. 도커 허브 조회 결과 litellm/litellm의 v1.106.2는 sha256:7294b90f868c5c38c99b83021c7ba46f9b439e95f8e32964c925c7d2563a03f7이다. 이 글을 쓰는 시점에 latest·main-latest·main-stable도 같은 값을 가리키고, v1.107.0은 404다. 이름표는 다시 옮겨질 수 있고 해시는 그럴 수 없다.
둘째, 해시까지 고정한다. 이 맥의 pip 26.1.2 도움말에 --require-hashes가 있다. 요구 사항마다 해시를 확인하는 옵션이다. 버전만 고정하면 같은 버전 이름으로 바뀐 파일은 못 막는다. 이번 사고는 새 버전 이름이었지만, 해시는 “받은 파일이 내가 검사한 그 파일인가”를 보장한다.
셋째, 새로 올라온 파일은 하루 묵힌다. 이 맥의 pip에는 --uploaded-prior-to라는 옵션이 있다. 올라온 지 일정 시간이 지난 파일만 후보로 삼는다. 직접 litellm을 받아 비교했다.
| 옵션 | 이 맥에서 고른 버전 |
|---|---|
| 없음 | 1.106.2 |
--uploaded-prior-to=P1D (1일 이상 지난 것) |
1.106.1 |
--uploaded-prior-to=P3D (3일) |
1.106.0 |
--uploaded-prior-to=P30D (30일) |
1.102.0 |
1.107.0은 올라온 지 2시간이 안 돼 내려갔다. 하루 묵히는 규칙이었다면 어느 시각에 설치해도 후보가 될 수 없었다. 대가도 있다. 긴급 보안 패치까지 하루 늦게 받는다. 그런 경우만 수동으로 예외를 두면 된다. 도움말에는 “업로드 시각 정보를 주는 인덱스에서만 효과가 있다”는 단서가 붙는다. 다른 버전의 pip는 pip install --help로 있는지부터 확인해야 한다.
증명서(attestation, 이 파일이 어느 빌드에서 나왔는지 서명으로 남기는 정보)도 짚어 둔다. 업윈드는 LiteLLM이 증명서를 게시한 적이 없다고 지적했다. 내가 PyPI 조회 주소로 litellm-1.106.2 wheel을 물으니 “No provenance available”(404)이 왔고, 같은 방식으로 pip 26.0 wheel은 200이 왔다. 그렇지만 회사 글은 악성 파일도 정식 파이프라인이 서명해 올렸다고 적었다. 그러니 증명서가 있었어도 이 사고를 막았을지는 이 글이 판단하지 못한다.
LiteLLM을 직접 돌리는 대신 게이트웨이 서비스를 쓰면 어떻게 다른지는 클라우드플레어 AI 게이트웨이 글의 비교표에 있다. 다만 그 표는 이번 사고 이전 기준의 비용·운영 비교이고, 어느 쪽이 더 안전한지를 말하는 표가 아니다.
해커뉴스가 문제 삼은 것: 두 번째라는 사실과 비공개 레지스트리
해커뉴스에는 394점, 댓글 123개가 달렸다(확인 시점 기준). 가장 많이 나온 말은 “이번이 두 번째”다. 3월 24일에도 1.82.7과 1.82.8이 변조돼 내려갔다는 보안 업체 보도가 있고, 지금 PyPI 버전 목록에서 1.82.6 다음이 곧바로 1.83.0인 것은 내가 확인했다. 한 댓글은 “한 번은 용서되지만 두 번은 직무 유기”라고 적었다. 회사 글의 입장은 정반대 방향이다. 3월 뒤 파이프라인을 강화했는데도 “독립된 보안 장치 여러 개를 차례로 뚫어야” 가능한 공격이었다고 적었다.
두 번째 쟁점은 쿨다운이다. 패키지 관리자의 기본값을 24~48시간 묵히게 바꾸자는 의견이 올라왔고, 위에서 시험한 옵션이 정확히 그 장치다.
세 번째는 보기에 따라 민감한 대목이다. 회사 직원의 답글에 “엔터프라이즈 고객용 비공개 레지스트리는 영향을 받지 않았다”는 문장이 있다. 같은 글에는 그 레지스트리로 10월 27일 공개 예정인 취약점의 수정본을 배포 중이라는 내용도 있다. 한 댓글은 이 문장이 “돈을 내고 비공개 쪽을 써야 안전하다”는 인상을 준다고 꼬집었다. 의도가 무엇이었는지는 알 수 없다. 회사 말로는 피해가 공개 설치 경로에서만 났다.
회사는 깃허브 답글에서 도커 이미지 저장소를 새 릴리스에 잠가 두었고 그 결과 일상적인 LiteLLM 릴리스가 멈춘다고 밝혔다. 한 사용자가 사후 분석과 릴리스 절차 공개를 요구했는데, 내가 읽은 답글에서는 그에 대한 회사의 약속을 찾지 못했다.
직접 재 본 일곱 가지와 회사 말에 기댄 부분
내가 직접 해 본 일이다.
- PyPI 조회:
litellm의 최신은 1.106.2(2026-10-21 10:44 UTC 업로드)이고 1.107.0은 목록에 없다.pip download litellm==1.107.0은 “No matching distribution found”로 실패했고, 목록은 1.107.0rc2에서 끝난다. - 1.106.2 맥(인텔)용 wheel(36.3MB, 파일 3,778개)을 내려받아 압축 목록만 읽었다.
.pth,sitecustomize.py,.data/purelib가 없다. 실행하지는 않았다. - 도커 허브 조회:
latest·main-latest·main-stable·v1.106.2는 같은 해시를 가리키고v1.107.0은 404다. - 깃허브 비교 조회: 커밋 10개, 시각, 메시지, 바꾼 파일 10개. 릴리스
v1.107.0은 404다(태그 목록에는-dev·-rc이름만 남음). - 가상환경에서 무해한
.pth와sitecustomize.py로 실행 시점 확인. - pip의
--uploaded-prior-to네 가지 시험과 PyPI 증명서 조회. - 이 맥에서
cook.pth검색, 설치된litellm확인.
회사 말이나 보안 업체 분석에 기댄 것도 있다. 정확한 시각(초 단위), 개발자 세 명의 자격증명이 쓰인 순서, 워크플로 기록 삭제, 도커 이미지 안의 파일, 수집 모듈 16개와 암호화 방식, 유출된 비밀이 실제로 쓰인 정황(위즈)은 직접 못 봤다. cook.py의 압축을 풀어 본 일도 없다. 안전한 환경이 아니면 열면 안 되는 파일이라서 일부러 하지 않았다. 마지막으로, 개발자 토큰이 어떻게 새어 나갔는지와 클로드 코드 관련 주장은 앞에서 적은 대로 회사의 추정이다. 확정된 것으로 옮겨 적지 않았다.
오늘 할 일은 한 줄이다. 한국 시각 10월 21일 저녁에 LiteLLM을 새로 설치했거나 이미지를 새로 받았다면, 지금 pip show litellm부터 보고 LiteLLM 악성 버전이 아닌지 가려 두자.