TanStack npm 공급망 공격, GitHub Actions의 취약점을 파고들다.
GitHub Actions 캐시 포이즈닝(Cache Poisoning)을 통해 악성 코드를 삽입, npm 패키지 공급망 공격 발생
OIDC 토큰 탈취(Token Extraction)를 통해 npm 패키지 배포 권한을 획득, 악성 버전 배포
외부 연구원의 신속한 탐지 및 보고로 피해 최소화, 대응 시간 20분 이내
GitHub Actions 보안 설정 미흡으로 인한 취약점 노출, ZIZMOR 스캔 등 보안 강화 필요
공격 벡터: GitHub Actions의 취약점
공격은 pull_request_target 패턴, GitHub Actions 캐시 포이즈닝(Cache Poisoning), 그리고 OIDC 토큰(OIDC Token) 추출을 결합하여 이루어졌다. 특히, PR 머지(Merge) 시 캐시된 악성 코드가 실행되도록 설계되었으며, 이는 GitHub Actions의 캐시 공유(Cache Sharing) 취약점을 악용한 것이다. 공격자는 이 취약점을 통해 OIDC 토큰을 탈취하고, npm 패키지를 악의적으로 배포했다.
악성 코드의 동작 방식
악성 코드는 npm install, pnpm install, 또는 yarn install 실행 시, optionalDependencies를 통해 실행된다. 실행된 코드는 AWS, GCP, Kubernetes, Vault, GitHub, npm, SSH 등 다양한 환경에서 자격 증명을 수집하고, Session/Oxen messenger를 통해 데이터를 유출한다. 또한, 감염된 패키지를 통해 다른 패키지를 재배포하는 자가 전파(Self-propagation) 기능을 가지고 있어, 광범위한 피해를 야기할 수 있다.
대응 및 교훈
사건 발생 후, 외부 연구원의 신속한 보고와 TanStack 팀의 즉각적인 대응으로 피해를 최소화했다. 하지만, 내부 알림 부재(Lack of Internal Alerting), pull_request_target 워크플로우(Workflow) 감사 미흡 등 개선해야 할 부분이 드러났다. ZIZMOR 스캔과 같은 보안 도구 도입, 서드파티 액션(Third-party Action)의 안전한 사용 등, 지속적인 보안 강화가 필요하다.
GitHub Actions 보안 강화 방안
이번 공격은 GitHub Actions의 pull_request_target 패턴의 위험성을 다시 한번 상기시킨다. 캐시 포이즈닝(Cache Poisoning)을 방지하기 위해, PR에서 생성된 캐시가 프로덕션 환경에 영향을 미치지 않도록 설정해야 한다. 또한, id-token: write 권한 사용 시, OIDC 토큰의 무분별한 사용을 막기 위해 Provenance(출처) 검증과 같은 추가적인 보안 조치를 고려해야 한다.