공식 소스코드는 멀쩡한데, 공식 배포 파일에는 악성 코드가 들어 있었습니다.
코드 검토도, 배포 승인도, 공식 빌드도 통과했습니다.
그런데 결과물은 자격증명을 훔치는 악성 패키지였습니다.
10월 21일, AI 모델 통합 도구 LiteLLM에서 실제로 발생한 공급망 공격입니다.
LiteLLM은 GPT, Claude, Gemini 등 여러 AI 모델을 하나의 API로 연결하고, 키와 사용량을 관리하는 오픈소스 도구입니다.
여러 AI 서비스를 연결하는 중간 계층이다 보니 기업의 AI API 키와 자격증명이 집중될 수 있는 구조입니다.
[무슨 일이 있었나]
공격자는 개발자 3명의 GitHub CLI 자격증명을 악용해 공식 배포 파이프라인을 변경했습니다.
브랜치 보호 규칙을 우회하고, 빌드에 사용되는 소스를 실제 LiteLLM 저장소가 아닌 이름이 비슷한 공격자 저장소로 바꿨습니다.
다른 개발자의 계정으로 승인 절차도 통과했습니다.
결과적으로 공식 파이프라인이 악성 코드를 포함한 LiteLLM 1.107.0을 배포했습니다.
PyPI에 악성 휠 7개가 약 1시간 43분 동안 공개됐고, Docker 이미지도 오염됐습니다.
[왜 더 위험했나]
악성 패키지에는 두 가지 기능이 들어 있었습니다.
첫째, 자격증명 탈취입니다.
SSH 키, 클라우드 계정, CI/CD 비밀정보, 브라우저 비밀번호뿐 아니라 Claude Code, Codex 등 AI 개발 도구의 인증 정보와 LiteLLM에 저장된 AI 모델 API 키까지 수집하도록 설계됐습니다.
둘째, 백도어입니다.
감염된 Python 환경에서는 LiteLLM을 직접 불러오지 않아도 Python 시작 과정에서 악성 코드가 실행될 수 있었습니다.
이후 외부 서버에서 추가 코드를 받아 실행하는 기능도 포함되어 있었습니다.
[그런데 공격자는 개발자 계정을 어떻게 확보했을까?]
LiteLLM 조사팀은 Claude Code의 응답에 GitHub CLI OAuth 토큰이 포함되고, 그 응답이 LiteLLM 로그에 기록될 수 있는 상황을 발견했습니다.
공격자가 외부에 노출된 내부 LiteLLM 환경의 로그를 통해 토큰을 확보했을 것으로 추정하고 있습니다.
아직 최초 침입 경로가 확정된 것은 아닙니다.
하지만 AI 개발 도구의 응답과 로그도 자격증명 유출 경로가 될 수 있다는 점을 보여주는 정황입니다.
[Hacker News에서 벌어진 논쟁]
흥미로운 것은 사고 이후 개발자들의 반응입니다.
"샌드박스를 사용하면 막을 수 있지 않나?"
"그 샌드박스나 프록시 자체가 침해되면?"
"공식 서명과 배포 승인까지 통과했는데 무엇을 믿어야 하나?"
"새 버전을 바로 설치하지 않고 며칠 기다리면 되지 않을까?"
하지만 업데이트 지연도 긴급 보안 패치를 늦출 수 있고, 패키지 서명은 빌드에 사용된 소스가 안전했다는 보장까지 제공하지는 않습니다.
다른 논쟁도 있었습니다.
LiteLLM 같은 대형 프레임워크를 쓰는 대신 필요한 기능만 직접 구현하면 공급망 위험을 줄일 수 있다는 주장입니다.
반대로 여러 AI 업체의 API 변경과 인증, 사용량 관리를 직접 유지보수하는 부담도 무시할 수 없습니다.
[이번 사고에서 중요하게 보는 부분]
단순히 악성 패키지가 배포된 문제가 아닙니다.
개발 도구의 로그에서 노출된 것으로 추정되는 자격증명이 GitHub 권한으로 이어졌고, 변경된 빌드 입력이 정상적인 승인·배포 절차를 거쳐 신뢰할 만한 패키지처럼 유통됐다는 점입니다.
개발 환경을 샌드박스로 격리하는 것만큼이나, 자격증명 접근 범위와 배포 권한을 분리하고, 실제 빌드 입력이 승인된 소스인지 검증하는 과정이 중요해 보입니다.
결국 공식 배포라는 사실과 안전한 배포라는 사실은 다릅니다.
개발 환경에서 현실적으로 보안을 강화한다면 어떤 방법부터 적용하시겠습니까?
개발 도구의 자격증명 격리, 배포 산출물 검증, 외부 패키지 의존성 축소 중 어디에 가장 우선순위를 두실지 궁금합니다.
#LiteLLM #공급망보안 #AI에이전트 #개발보안