|| 들어가며
안녕하세요, 당근 파이썬 챕터에서 활동하고 있는 데니와 엘빈이에요. 당근에는 특정 프로그래밍 언어에 관심 있는 구성원들이 자발적으로 모여 해당 언어의 전사 정책과 생태계 이슈를 논의하는 챕터 그룹이 있어요. Go, Ruby 등 여러 언어를 위한 챕터가 각각 운영되고 있고, 파이썬 챕터도 그 중 하나예요.
이번 글은 파이썬 챕터에서 공급망 보안 이슈를 논의한 후 실제로 사내 인프라에 적용한 과정을 공유해요. 비슷한 고민을 하고 있는 분들께 도움이 됐으면 좋겠어요.
사건의 발단: LiteLLM 공급망 공격
2026년 3월 24일, LLM 프록시 라이브러리로 널리 쓰이는 LiteLLM의 PyPI 패키지가 **공급망 공격(supply chain attack)**을 받았어요.
공격이 일어난 과정은 아래와 같아요.
LiteLLM은 보안을 위해 Trivy라는 보안 스캐너를 CI/CD에서 작동시키고 있었어요.
공격자는 LiteLLM의 CI/CD에서 사용하던 Trivy의 크리덴셜을 탈취했어요.
탈취한 크리덴셜로 공식 CI/CD 파이프라인을 우회해, 악성 코드가 삽입된 패키지(1.82.7, 1.82.8)를 PyPI에 직접 업로드했어요.
해당 버전에는 환경 변수, SSH 키, 클라우드 크리덴셜을 외부로 탈취하는 페이로드가 포함돼 있었어요.
악성 패키지는 PyPI에 의해 비교적 빠르게 격리됐지만, 그 짧은 시간 동안에도 상당한 수의 다운로드가 발생했어요. 비슷한 시기에 telnyx 패키지도 같은 방식으로 공격을 받았어요.
왜 쿨다운인가
이런 공급망 공격에는 공통적인 패턴이 있어요. 악성 패키지가 PyPI에 업로드된 직후부터 탐지·격리까지 노출 시간(exposure window)이 짧다는 점이에요.
William Woodruff의 분석(We should all be using dependency cooldowns)에 따르면, 최근 열 건의 주요 공급망 공격 중 여덟 건의 노출 시간이 일주일 미만이었어요. 14일 쿨다운을 적용했다면 그 중 아홉 건을 사전에 차단할 수 있었고요.
아이디어 자체는 단순해요. 패키지가 PyPI에 올라온 직후에는 설치하지 말고, 며칠을 기다리는 거예요. 악성 패키지가 탐지·격리되기까지 시간이 걸리고, 그 전설치하는 게 문제니까요.
일부 도구는 이를 기본적으로 지원하고 있어요.
uv: exclude-newer = "P3D" 설정으로 3일 이내 업로드된 패키지 제외
pip: -uploaded-prior-to 플래그
당근의 사내 PyPI 프록시
당근에서는 사내 라이브러리를 PyPI 형태로 배포하고 관리하기 위해 AWS CodeArtifact를 사용하고 있어요. 이를 구성원들이 더 쉽게 활용할 수 있도록 사내 PyPI 프록시 서버를 운영하고 있어요.
왜 별도의 프록시가 필요했나
CodeArtifact의 endpoint를 그대로 노출해도 패키지를 받는 데에는 문제가 없어요. 다만 그러려면 모든 환경에서 AWS 자격 증명을 챙긴 다음, 매번 토큰을 발급받아 URL에 끼워 넣는 작업을 거쳐야 해요.
예를 들어 로컬에서 uv를 쓰려면 이런 식의 환경 변수 설정이 필요했어요.
$ export UV_INDEX="<https://aws>:$(
aws codeartifact get-authorization-token \
--domain xxxx-yyyy \
--domain-owner <AWS_ACCOUNT_ID> \
--query authorizationToken \
--output text
)@xxxx-yyyy-<AWS_ACCOUNT_ID>.d.codeartifact.us-west-2.amazonaws.com/pypi/xxxx-yyyy/simple/"
파이썬 패키지를 설치하고 싶었을 뿐인데 awscli를 설치해야 하고, 셸에서 AWS 자격 증명이 유효해야 하고, get-authorization-token으로 받은 토큰을 URL에 직접 넣어야 했어요. 토큰은 일정