라떼군 이야기


42분 만에 막은 PyTorch Lightning PyPI 공급망 공격

2026년 4월 30일, PyPI에 올라온 lightning 패키지 2.6.2와 2.6.3에 악성 코드가 삽입됐다. Lightning AI 커뮤니티가 이상을 발견하고 대응하기까지 걸린 시간은 42분이었다. 공식 블로그 제목도 이 숫자를 내세운다. “How the PyTorch Lightning Community Discovered a Supply Chain Attack and Fixed it in 42 Minutes.”

42분은 빠른 대응이다. 그러나 그사이 pip install lightning을 실행했거나 lightning>=2.6처럼 버전 범위를 지정한 환경은 악성 버전을 설치했을 수 있다. ML 훈련 파이프라인과 CI/CD 시스템, 개발자 PC 가운데 얼마나 많은 환경이 실제로 영향을 받았는지는 아직 공개되지 않았다.

ML 생태계에서 공급망 공격이 더 위험한 이유

소프트웨어 공급망 공격은 새로운 문제가 아니다. 신뢰받는 패키지나 배포 경로를 장악한 뒤 악성 코드를 사용자에게 전달하는 방식은 여러 생태계에서 반복돼 왔다.

ML 환경에는 이 위험을 키우는 몇 가지 구조적 특성이 있다.

1. 의존성 버전을 느슨하게 관리한다. requirements.txttorch>=2.0처럼 범위만 지정하는 경우가 많다. 새 환경을 만들 때마다 PyPI의 최신 버전을 받아오는 구조다. 일반적인 애플리케이션 개발에서는 잠금 파일과 의존성 자동 점검이 널리 쓰이지만, 실험 중심의 데이터 과학 환경에서는 아직 일관되게 적용되지 않는 경우가 많다.

2. GPU 노드는 통제에서 벗어나기 쉽다. 온디맨드 GPU 인스턴스는 보통 스크립트로 생성한 뒤 pip install -r requirements.txt로 환경을 구성한다. 이미지와 패키지 버전을 고정하지 않으면 새 인스턴스가 만들어질 때마다 다른 의존성이 설치될 수 있다. 훈련 클러스터의 외부 통신이 열려 있다면 악성 코드가 자격증명이나 데이터를 외부로 전송하기도 쉽다.

3. 패키지 배포 계정과 토큰은 매력적인 공격 대상이다. Lightning 사건의 정확한 침해 경로는 공식 조사에서 아직 확정되지 않았다. 따라서 PyPI 계정 탈취였다고 단정해서는 안 된다. 다만 유지관리자 계정이나 장기 API 토큰, 배포용 CI 워크플로를 장악하는 것은 널리 쓰이는 패키지를 변조하는 효율적인 방법이다.

PyPI는 2024년 1월부터 모든 사용자에게 관리 작업과 업로드를 위한 2단계 인증을 요구한다. 그러나 2단계 인증만으로 유출된 API 토큰이나 손상된 배포 워크플로까지 막을 수는 없다. 가능하다면 장기 토큰 대신 짧은 수명의 OIDC 자격증명을 발급하는 Trusted Publishing을 사용하는 편이 안전하다.

4. 악성 코드가 접근할 수 있는 자산이 많다. ML 훈련 환경에는 원본 데이터와 모델 가중치, 클라우드 자격증명, 실험 추적 서비스 토큰, 고가의 GPU 자원이 한곳에 모여 있다. Lightning AI의 보안 권고는 악성 버전에서 자격증명 수집과 일치하는 기능이 확인됐다고 설명한다. 영향받은 환경은 단순히 패키지를 제거하는 데 그치지 말고, 노출 가능성이 있는 자격증명을 교체하고 깨끗한 상태에서 다시 구축해야 한다(GitHub 보안 권고).

ML 파이프라인의 의존성 관리 원칙

버전과 해시를 함께 고정하라

# 위험
lightning>=2.6

# 권장
lightning==2.6.1

운영 환경에서 사용하는 패키지는 정확한 버전으로 고정해야 한다. pip-toolspip-compile, Poetry의 poetry.lock, conda-lock.yml 등을 이용해 간접 의존성까지 잠그고 결과를 저장소에 포함한다.

버전 고정만으로는 부족하다. 공격자가 같은 버전의 배포 파일을 바꾸거나 내부 미러가 오염될 가능성도 고려해야 한다.

pip install --require-hashes -r requirements.txt

pip-compile --generate-hashes로 각 배포 파일의 SHA-256 해시를 생성하면 설치 과정에서 파일 무결성을 확인할 수 있다.

컨테이너 이미지도 다이제스트로 고정하라

FROM pytorch/pytorch:2.3.1-cuda12.1-cudnn8-runtime@sha256:...

latest 태그는 같은 Dockerfile로도 시점에 따라 다른 이미지를 가져올 수 있다. 베이스 이미지는 다이제스트로 고정하고, 이미지 안에 설치하는 Python 패키지도 잠금 파일과 해시로 관리해야 한다.

Docker 레이어 캐시가 적중하면 설치 명령이 다시 실행되지 않는다. 문제는 캐시가 무효화되거나 새 빌드 환경에서 이미지를 만들 때다. 이때 버전이 느슨하면 최신 패키지가 예고 없이 들어온다.

취약점 감사 도구의 한계를 이해하라

pip-audit 같은 도구는 알려진 취약점이 포함된 의존성을 찾는 데 유용하다. CI에 연결해 취약한 버전이 발견되면 빌드를 중단할 수도 있다.

그러나 이런 도구는 취약점 데이터베이스에 아직 등록되지 않은 악성 릴리스를 즉시 탐지하지 못한다. Lightning 사건처럼 발견과 대응이 42분 안에 이뤄진 경우에는 감사 도구보다 버전 고정, 승인된 미러, 네트워크 통제와 실행 시점 감시가 더 직접적인 방어 수단이다.

PEP 740에 따른 디지털 증명은 패키지의 출처와 배포 과정을 검증하는 기반을 제공한다. 다만 PEP 740은 설치 도구가 모든 패키지의 증명을 의무적으로 검증하도록 규정하지 않는다. 서명이나 증명이 존재한다는 사실과 실제 설치 정책에서 이를 강제하는 것은 별개의 문제다.

승인된 패키지만 내부로 들여와라

규모가 있는 조직이라면 PyPI에서 직접 설치하기보다 Artifactory나 Nexus 같은 내부 레지스트리를 두는 편이 낫다. 새 버전은 검사와 승인 과정을 거친 뒤 내부 저장소에 등록한다.

업데이트 속도는 다소 느려지지만, 공개 저장소에 올라온 패키지가 곧바로 훈련 환경에 들어오는 일을 막을 수 있다. 중요한 것은 단순한 프록시 캐시가 아니라 승인 전과 승인 후의 저장소를 분리하는 것이다.

공급망 공격을 감지하는 방법

42분 대응에서 중요한 것은 새 버전의 비정상적인 동작을 빠르게 알아챘다는 점이다. 조직 내부에서도 여러 감지 수단을 겹쳐야 한다.

  1. 패키지 설치와 초기 실행 단계의 외부 통신을 차단하거나 기록한다. 평소 접속하지 않던 호스트로 연결하면 경보를 보낸다.
  2. 훈련 작업에는 필요한 자격증명만 짧게 발급한다. 개발자 개인 토큰이나 광범위한 클라우드 권한을 전달하지 않는다.
  3. 모델 가중치와 데이터셋, 컨테이너 이미지의 체크섬을 실행 전후로 확인한다.
  4. 새 패키지 버전은 격리된 환경에서 정적 분석과 행위 분석을 거친다. YARA나 악성 코드 검사 서비스는 보조 수단으로 사용한다.
  5. PyPI 릴리스와 보안 권고를 구독하되, 알림을 받았다는 이유만으로 자동 업데이트하지 않는다.

아직 확인되지 않은 것

공식 보안 권고에 따르면 2.6.2와 2.6.3은 자격증명 수집과 일치하는 악성 기능을 포함했다. 하지만 침해의 정확한 시작점과 전체 동작, 실제 다운로드 수, 영향을 받은 환경의 수는 아직 공개되지 않았다. 공격 주체도 확인되지 않았다.

따라서 현재 단계에서 “PyPI 계정이 탈취됐다”거나 “특정 악성 코드 계열이 사용됐다”고 단정하는 것은 이르다. 추가 조사 결과가 나오면 침해 경로와 대응 타임라인을 보완해야 한다.

구조적 문제는 남아 있다

PyTorch Lightning 커뮤니티는 빠르게 대응했다. 다음 공격도 42분 만에 발견된다는 보장은 없다. 날짜마다 내용이 달라지는 나이틀리 패키지, 소수의 유지관리자가 관리하는 유틸리티, Notebook에서 무심코 실행하는 !pip install, 외부 통신이 자유로운 GPU 클러스터는 여전히 넓은 공격 표면을 만든다.

pip install은 코드를 내려받아 현재 사용자의 권한으로 실행하는 행위다. 명령이 익숙하고 짧다는 이유만으로 더 안전해지는 것은 아니다.

참고

[1] Lightning AI. How the PyTorch Lightning Community Discovered a Supply Chain Attack and Fixed it in 42 Minutes.

[2] Lightning AI. GitHub 보안 권고 GHSA-w37p-236h-pfx3.

[3] PyPA. pip-audit. PyPI.

[4] Python. PEP 740: Index support for digital attestations.

[5] PyPI. Trusted Publishing. PyPI Docs.

[6] PyPI. 2단계 인증 의무화 안내. PyPI Blog, 2024-01-01.

제품 기획·개발 파트너 찾으시나요? 개인·팀·기업 모두 환영. 문제 정의부터 출시까지 함께합니다.

Copyright © 2026 - present Mr. Latte. All Rights Reserved.

hello@mrlatte.net

v2026.08.25.0628