TanStack npm 공급망 공격 발생: CI 토큰 탈취 및 소스 코드 유출 경위

TanStack npm 공급망 공격은 GitHub Actions의 pull_request_target 워크플로 취약점과 캐시 오염을 이용해 CI 환경의 OIDC 토큰 및 자격증명을 탈취한 뒤, 다수의 npm 패키지에 악성 버전을 배포한 사건입니다. 이 공격으로 42개의 TanStack 패키지에 총 84개의 악성 버전이 게시되었고, 연쇄적으로 타 기업의 비공개 리포지토리까지 유출되었습니다.

TanStack npm 공급망 공격 개요 및 영향

이번 공격은 단순한 패키지 변조를 넘어 CI/CD 파이프라인의 신뢰 체계를 무너뜨린 전형적인 공급망 공격(Supply-chain compromise) 사례입니다. 공격자는 짧은 시간에 악성 코드를 몰아서 배포해 탐지 시간을 최소화하고 피해 규모를 키우려 했습니다.

공격자는 UTC 기준 19:20부터 19:26까지 단 6분 동안 @tanstack/* 네임스페이스의 패키지 42개에 걸쳐 총 84개의 악성 버전을 게시했습니다. 악성 버전은 CI 및 빌드 환경에서 접근 가능한 GitHub, npm, SSH 자격증명을 탈취하도록 설계되었습니다.

취약점은 CVE-2026-45321로 식별되었으며, TanStack 측은 이에 대응하는 보안 업데이트를 발표하고 추적 이슈(TanStack/router#7383)와 GitHub 보안 자문(GHSA-g7cv-rxg3-hmpx)을 공개해 개발자들의 주의를 촉구했습니다.

공격 메커니즘: GitHub Actions 취약점 및 자격증명 탈취 경로

이번 공격의 핵심은 ‘TeamPCP’로 명명된 공격 그룹이 사용한 ‘Shai Hulud’라는 자격증명 탈취 특화 악성코드와 정교한 워크플로 공격 패턴입니다. 공격 과정은 크게 세 가지 기술 단계로 구성되었습니다.

  1. Pwn Request 패턴 이용: pull_request_target 이벤트의 특성을 악용한 것으로, 외부 포크(Fork)에서 생성된 PR(Pull Request)임에도 워크플로가 베이스 리포지토리의 컨텍스트에서 실행되도록 유도했습니다.
  2. GitHub Actions 캐시 오염: 포크 리포지토리와 베이스 리포지토리 사이의 신뢰 경계를 넘어 GitHub Actions 캐시를 오염시켰습니다.
  3. OIDC 토큰 추출: 캐시 오염으로 실행 제어권을 확보한 뒤, 실행 중인 메모리에서 OIDC(OpenID Connect) 토큰을 직접 추출해 권한을 얻었습니다.

공격자는 정상적인 CI 프로세스를 가장해 관리자 권한의 토큰을 탈취했고, 이 권한으로 npm 레지스트리에 악성 패키지를 직접 게시할 수 있게 되었습니다.

연쇄 피해 사례: CrowdSec 소스 코드 유출

TanStack 공격에서 관측된 동일한 공격 경로가 다른 조직의 데이터 유출 사고에서도 발견되었습니다. 특히 보안 기업 CrowdSec의 사례는 CI 토큰 탈취가 얼마나 큰 2차 피해로 이어지는지 보여줍니다.

분석 결과, CrowdSec의 전직 임직원 계정이 오염되었고, 이 계정으로 약 170개의 비공개 GitHub 리포지토리에 접근해 2026년 5월 당시의 소스 코드가 노출되었습니다. 구체적으로는 ‘encracked(diencracked@cock.li)’라는 계정이 토론토(UTC-4) 지역 IP에서 해당 리포지토리들을 내려받은 것으로 확인되었습니다.

이 전직 임직원은 소스 코드 유출 사고가 발생하고 3일 뒤인 2026년 5월 25일에 GitHub 조직에서 제거되었습니다. 계정 관리와 권한 회수 프로세스의 허점이 공급망 공격의 결과와 맞물렸을 때 얼마나 치명적인지를 보여주는 대목입니다.

공격 및 피해 요약 분석

이번 TanStack npm 공급망 공격의 주요 구성 요소와 피해 현황을 표로 정리했습니다.

구분 상세 내용
취약점 식별 번호 CVE-2026-45321
공격 그룹 및 코드 TeamPCP / Shai Hulud
악성 패키지 규모 @tanstack/* 42개 패키지, 84개 버전
공격 수행 시간 19:20 ~ 19:26 UTC (약 6분간)
주요 탈취 대상 GitHub, npm, SSH 자격증명 및 OIDC 토큰
외부 피해 사례 CrowdSec 비공개 리포지토리 약 170개 유출

대응 방안 및 재발 방지책

이번 사고는 CI/CD 환경의 설정 오류가 에코시스템 전체의 보안 붕괴로 이어질 수 있음을 보여줍니다. pull_request_target처럼 강한 권한을 가진 워크플로를 다룰 때는 각별한 주의가 필요합니다.

개발자와 DevOps 담당자가 점검할 조치는 다음과 같습니다.

  • 워크플로 권한 최소화: pull_request_target을 쓸 때는 외부 입력값 검증을 강화하고, 불필요한 권한 할당은 최소화하는 것이 안전합니다.
  • 캐시 무결성 검증: 포크된 리포지토리 간의 캐시 공유 설정과 신뢰 경계를 재점검해 캐시 오염 공격에 대비합니다.
  • 자격증명 관리 강화: OIDC 토큰의 유효 기간을 최소화하고, 전직 임직원 등 퇴사자의 접근 권한을 즉시 회수하는 엄격한 계정 라이프사이클 관리가 필요합니다.
  • 의존성 모니터링: CVE-2026-45321처럼 식별된 취약점에는 보안 업데이트를 신속히 적용하고, 사용 중인 @tanstack 패키지의 버전을 확인해 악성 버전이 섞여 있는지 점검하면 됩니다.

댓글 남기기