의존성 설치의 신뢰는 어디서 깨지나: 이름, 패키지 매니저, 바이너리
AI가 제안한 패키지 이름이 실제로 존재하는지, 패키지 매니저가 내려받은 파일의 변경을 막는지, 배포된 바이너리가 소스와 일치하는지는 서로 다른 검증 문제입니다. 세 자료를 비교하면 한 단계의 확인만으로는 다음 단계의 위험까지 해결할 수 없으며, 각 경계에서 무엇을 확인하는지가 달라집니다.
이름 확인은 패키지를 고르는 단계의 방어다
‘AI가 추천한 패키지 5개 중 1개는 존재하지 않습니다 — 공격자는 그 이름을 알고 있습니다’는 AI가 만들어낸 패키지 이름을 공격자가 먼저 등록해 악성 코드를 심는 슬롭스쿼팅을 다룹니다. 이 글이 인용한 2025년 연구에서는 16개 LLM의 추천 패키지 중 19.7%가 환각이었고, 같은 질문을 반복했을 때 환각 이름의 43%가 매번 다시 나왔습니다. 따라서 위험은 단순히 설치가 실패하는 데 그치지 않습니다. 반복해서 나오는 이름은 공격자가 미리 등록할 수 있습니다.
이 위협은 패키지 매니저의 파일 무결성 확인과 다른 지점에 있습니다. 이름이 그럴듯한지, 실제로 존재하는지 확인하는 것은 악성 패키지를 선택하지 않도록 하는 일입니다. 글은 AI가 추천한 이름을 검증되지 않은 입력으로 취급하고 설치 전에 존재 여부와 이력 등을 확인하라고 제안합니다. 반면 이 확인만으로, 이미 선택한 패키지를 내려받는 과정에서 파일이 변조되는지까지 판별할 수 있다고 말하지는 않습니다.
패키지 매니저의 무결성 검증은 내려받은 파일을 다룬다
‘패키지 매니저에는 무결성 문제가 있습니다’는 악성 패키지 이름의 선점이 아니라, 정상 패키지를 제공하는 저장소가 침해되어 내려받은 파일에 코드가 주입되는 상황을 시험합니다. 저자는 25개 패키지 매니저를 조사해 절반 미만이 기본적으로 변조를 확인하는 lockfile을 사용했고, 내려받는 모든 패키지의 무결성을 검증한 것은 두 종류뿐이었다고 보고합니다. 이 실험은 특정 구성과 버전을 대상으로 했고, 저자도 모든 개발자가 취약하다는 뜻은 아니라고 한정합니다.
이 글에 따르면 npm, pnpm, Poetry, uv 등은 lockfile이 있을 때 해시를 검증하는 쪽에 포함되지만, 일부 도구는 추가 설정이 필요하거나 해시가 없고, 해시가 있어도 설치를 막지 않거나 실제 받은 파일의 무결성을 보장하지 않는 경우가 있습니다. 예컨대 Pub은 해시 불일치를 감지해도 기본 설정에서는 설치를 계속하며, 차단하려면 별도 옵션이 필요합니다. 그러므로 ‘lockfile을 쓴다’는 사실만으로 보호 수준을 단정하기보다, 실제 설정에서 불일치가 차단되는지 확인해야 합니다.
앞선 AI 패키지 이름 글이 설치 전 이름 확인과 새 의존성 검토를 강조하는 것과 달리, Trail of Bits의 실험은 저장소에서 받은 내용이 변조됐는지에 초점을 둡니다. 두 확인은 서로 대체되지 않습니다. 이름을 확인해 올바른 패키지를 골랐더라도 내려받는 과정의 무결성은 별도 문제이며, 반대로 파일 검증만으로 AI가 지어낸 이름을 올바른 의존성으로 바꿀 수도 없습니다.
바이너리와 소스의 일치는 또 다른 검증 경계다
‘Python 바이너리 휠과 공급망 공격’은 PyPI에서 소스 코드가 아니라 미리 컴파일된 휠을 설치하는 경우를 다룹니다. 글에 따르면 공격자는 깨끗한 소스 코드와 악성 바이너리를 함께 올릴 수 있고, PyPI 업로드 때 바이너리가 해당 소스에서 빌드됐는지 확인하는 적절한 방법이나 의무적인 바이너리 증명은 없다고 합니다. 소스 코드를 주로 분석하는 스캐너만으로는 이런 불일치를 놓칠 수 있다는 것이 이 글의 우려입니다.
이 문제는 패키지 이름의 존재 여부나 패키지 매니저가 받은 파일의 해시 확인과도 구별됩니다. 해시는 다운로드한 파일이 기준 파일과 같은지 확인할 수 있지만, 그 기준이 소스와 바이너리의 대응 관계를 증명하는지는 별도 문제입니다. 세 번째 글은 이 간극을 지적하며 현재 자신이 보는 해결책으로 Python 의존성을 직접 컴파일하고 최신 버전을 바로 설치하지 않는 방안을 제시합니다. 이는 해당 글 저자의 제안이지, 다른 두 자료가 함께 입증한 보편적 해결책은 아닙니다.