의존성 혼동·타이포스쿼팅 공급망 공격 분석

Security · 공급망·패키지 · 공급망 공격 개념 [정보성]

현대 소프트웨어는 수백 개의 외부 패키지 위에 올라갑니다. 그래서 공격자가 노리는 곳도 우리가 짠 코드가 아니라, 우리가 신뢰하고 당겨 쓰는 이름입니다. 의존성 혼동과 타이포스쿼팅은 서로 다른 기법이지만 뿌리가 같습니다. 둘 다 패키지 매니저가 “이름을 어떻게 믿고 어디서 가져올지” 정하는 방식의 빈틈을 파고듭니다. 이 글은 각 기법의 메커니즘과, 그것이 왜 반복될 수밖에 없는 구조적 원인인지를 짚습니다.

핵심 사실 요약

의존성 혼동 — 30초 개념

보안 연구자 Alex Birsan은 2021년 2월 9일 “dependency confusion”이라는 기법을 공개했습니다. 핵심은 이렇습니다. 많은 조직이 사내 전용 패키지를 사설(내부) 레지스트리에 두고, 동시에 공개 레지스트리(npm·PyPI 등)도 함께 참조하도록 패키지 매니저를 설정합니다. 이때 같은 이름의 패키지가 양쪽에 모두 존재하면, 해석(resolution) 설정에 따라 공개 쪽이 선택될 수 있습니다. 공격자는 기업 내부 패키지의 이름을 알아낸 뒤, 공개 레지스트리에 같은 이름으로 패키지를 올립니다.

두 번째 구조적 원인은 버전 우선순위입니다. 일부 해석 설정은 출처(사설/공개)와 무관하게 더 높은 버전 번호를 설치합니다. 그래서 공격자가 공개 레지스트리에 더 높은 버전을 올리면, 클라이언트가 그것을 “최신”으로 받아들여 자동으로 당겨옵니다. (⚠️미확인: 이 “더 높은 버전 우선” 동작이 특정 레지스트리(예: PyPI)에서 구체적으로 관찰됐다는 서술은 Birsan 원문에 근거하나 원문이 접근 불가라 직접 대조하지 못했으며, 당겨 쓰는 인용 출처 중에서는 일반적 메커니즘 서술만 확인됩니다.)

어떻게 “실행됨”이 증명됐나

Birsan은 각 패키지에 설치 단계(preinstall) 스크립트를 넣어, 설치가 일어난 환경의 식별 정보를 DNS 질의로 외부에 내보내는 방식으로 코드가 실제로 돌았음을 입증했습니다. 이 글은 그 개념만 소개하며, 작동하는 페이로드나 완성형 익스플로잇은 다루지 않습니다.

이 실험의 사정거리는 좁지 않았습니다. 35개 이상의 대형 기술 기업이 대상이 됐고, 공개된 사례에는 Microsoft·Apple·PayPal·Shopify·Netflix·Tesla·Yelp·Uber가 포함됩니다. 연구자는 모든 대상이 사전 테스트 허가를 제공했다고 명시했습니다. (⚠️미확인: “35개 이상”의 전체 명단은 출처마다 일부 예시만 나열해 전부를 확정할 수 없습니다.) 대상 생태계는 npm·PyPI·RubyGems 세 곳이었습니다. 버그바운티·펜테스트 보상 합계는 13만 달러를 넘었고, 그중 Microsoft가 4만 달러로 최고액, PayPal이 3만 달러였습니다.

Microsoft는 이 문제를 CVE-2021-24105(패키지 매니저 구성 관련 원격 코드 실행)로 식별하고, 저장소 자체의 수정이 아니라 재구성이 필요한 설계상 결함으로 분류했습니다. (⚠️미확인: CVE-2021-24105의 정확한 CVSS 점수와 세부 영향 범위는 NVD 1차 레코드를 직접 대조하지 않아 확정하지 않습니다.)

타이포스쿼팅 — 오타 한 번을 노린다

타이포스쿼팅은 인기 있는 정식 패키지와 철자가 비슷한 이름으로 악성 패키지를 공개해, 개발자의 오타 설치를 노리는 기법입니다. 구조적 원인은 두 가지입니다. 첫째, 레지스트리가 거의 모든 이름의 자유 등록을 허용합니다. 둘째, 설치 시점에 코드(설치 스크립트)가 실행됩니다. 그래서 오타 한 번이 공격자 코드의 실행으로 바로 이어집니다.

이름을 만들기도 쉽습니다. 한 분석은 과거 타이포스쿼트 40건 중 18건이 대상과 레벤슈타인 거리(Levenshtein distance) 2 이하였다고 정리합니다. 글자 한두 개만 바꿔도 유효한 공격 이름이 만들어진다는 뜻입니다.

역사적 사례도 공개돼 있습니다. 2016년 Nikolai Tschacher의 학사 논문 실험은 오타 이름의 패키지로 1만 7천 대 이상의 머신을 감염시켰고, 그중 약 절반이 관리자 권한으로 코드를 실행했다고 전해집니다(PyPI·npm·RubyGems 대상). 2017년 npm의 cross-env 사례에서는 구분자(하이픈) 정규화 차이를 악용한 변종이 적발 전 700대 이상에 내려받아졌습니다. (⚠️미확인: 이 두 수치는 널리 인용되지만 2차 해설 출처에 기반한 것으로, 원 논문·원 사건 보고서를 직접 대조하지는 않았습니다.)

최근에는 “slopsquatting”이라는 변종도 거론됩니다. 오타가 사람의 손가락이나 튜토리얼 복사·붙여넣기에서만 오는 게 아니라, 대규모 언어 모델(LLM)이 환각(hallucination)으로 지어낸 존재하지 않는 패키지 이름에서도 올 수 있다는 관점입니다.

왜 반복되는가 — 같은 뿌리

두 기법은 겉모습이 다르지만 같은 전제를 공유합니다. 패키지 매니저가 “이름”을 신뢰의 단위로 쓴다는 점입니다. 의존성 혼동은 “같은 이름이면 더 높은 버전·공개 출처를 믿는” 해석 규칙을 역이용하고, 타이포스쿼팅은 “비슷한 이름을 사람이 혼동하는” 인지의 틈을 역이용합니다. 어느 쪽도 특정 제품의 코드 버그가 아닙니다. 생태계가 편의를 위해 받아들인 기본 동작이 그대로 공격 표면이 됩니다. Microsoft가 이를 코드 수정이 아니라 재구성 문제로 분류한 것도 같은 맥락입니다.

그래서 방어도 “한 줄 패치”가 아니라 설정과 규율의 문제가 됩니다. 이름을 어디서 믿을지, 어떤 버전을 신뢰할지를 조직이 명시적으로 정해야 빈틈이 닫힙니다.

대응방안

  • 출처 고정: Microsoft 백서 “3 Ways to Mitigate Risk Using Private Package Feeds”는 세 가지를 권고합니다. 첫째, 사설 피드 하나만 참조하고 공개 패키지는 사설 저장소로 끌어와 관리합니다. 둘째, 스코프·네임스페이스·프리픽스(예: npm의 scope)로 내부 패키지 이름을 보호합니다. 셋째, 클라이언트 측 검증(버전 고정·무결성 검증)으로 예기치 않은 변경이 생기면 빌드를 중단합니다.
  • 차선책: 위 구성을 당장 바꾸기 어렵다면, 내부 패키지 이름을 공개 레지스트리에 방어적으로 선점(네임스페이스 등록)하고, 설치 전에 의존성 목록과 출처를 사람이 확인하는 절차를 둡니다.
  • 탐지 관점: 새로 추가된 의존성의 출처·버전 급변, 설치 스크립트의 외부 네트워크 질의 같은 신호를 빌드 로그에서 살핍니다.

짧은 논평

이름을 신뢰 단위로 쓰는 한, 이 계열의 공격은 도구가 바뀌어도 다른 자리에서 또 나타납니다. slopsquatting처럼 새 변종이 계속 파생되는 것도 그래서입니다. 한 번의 설정 변경으로 특정 틈은 닫히지만, “이름을 어떻게 믿을 것인가”라는 질문 자체는 남습니다. 그래서 우리는 개별 사례의 재현 절차보다, 옮겨 쓸 수 있는 이 구조적 원리를 기록으로 남깁니다.


References / 참고자료

  1. Catalin Cimpanu, “Researcher hacks Microsoft, Apple, more in novel supply chain attack,” BleepingComputer, 2021-02-09 — 의존성 혼동의 발견·메커니즘·대상·보상·CVE 식별의 바탕이 된 보도. https://www.bleepingcomputer.com/news/security/researcher-hacks-microsoft-apple-more-in-novel-supply-chain-attack/
  2. The Hacker News, “New ‘Dependency Confusion’ supply chain attack” — Microsoft 완화 백서의 세 권고와 공격 전제 조건 정리. https://thehackernews.com/2021/02/dependency-confusion-supply-chain.html
  3. TechRadar, “Microsoft sounds the alarm over new ‘dependency confusion’ attack technique.” https://www.techradar.com/news/microsoft-sounds-the-alarm-over-new-dependency-confusion-attack-technique (⚠️미확인: 페이지가 멤버십 게이트로 막혀 본문 내용을 직접 대조하지 못했습니다.)
  4. Andrew Nesbitt, “Typosquatting in package managers,” nesbitt.io, 2025-12-17 — 타이포스쿼팅 메커니즘·역사 사례(Tschacher·cross-env)·레벤슈타인 통계·slopsquatting의 바탕. https://nesbitt.io/2025/12/17/typosquatting-in-package-managers.html
  5. Wenxin Jiang, Berk Çakar, Mikola Lysenko, James C. Davis, “ConfuGuard: Using Metadata to Detect Active and Stealthy Package Confusion Attacks Accurately and at Scale,” arXiv:2502.20528 — 패키지 혼동·타이포스쿼팅 탐지에 관한 학술 배경 참고. https://arxiv.org/abs/2502.20528v1
  6. Vulert, “Dependency Confusion Attacks — How They Work and How to Protect Your Pipeline” — 사설·공개 레지스트리 혼용이라는 핵심 전제의 보조 설명. https://vulert.com/blog/dependency-confusion-attack
  7. Sonatype, “Are you still wondering about dependency confusion attacks?” — 네임스페이스·동일 이름 충돌이라는 핵심 전제의 보조 설명. https://www.sonatype.com/blog/are-you-still-wondering-about-dependency-confusion-attacks
  8. Apiiro Glossary, “Typosquatting.” https://apiiro.com/glossary/typosquatting/ (⚠️미확인: 접근 시 HTTP 403이 반환되어 페이지 내용을 직접 대조하지 못했습니다.)

이 글은 위 출처들을 우리 관점에서 다시 쓰고 논평을 더한 것입니다. 특정 문장·코드를 그대로 옮기지 않았으며, 자세한 내용은 원문을 참고하세요. Birsan의 원문(Medium)은 접근이 막혀 직접 대조하지 못했고, 해당 수치는 2차 교차확인 상태임을 밝힙니다.