
안녕하세요,
그로메트릭 입니다. 🐸
오픈소스 생태계를 겨냥한 대규모 공급망 공격이 다시 돌아왔습니다. 'Shai-Hulud Miasma'로 명명된 이번 캠페인은 npm 패키지 생태계 전반에 300개가 넘는 악성 패키지 버전을 유포하며, 개발자 환경과 CI/CD 파이프라인을 침투 경로로 삼아 자격 증명을 탈취하고 스스로 퍼져나가는 웜(worm) 형태의 공급망 공격입니다.
이번 변종이 특히 주목받는 이유는 기존 탐지 방식을 교묘히 우회했기 때문입니다.
대부분의 보안 가이드라인은 package.json의 preinstall·postinstall 스크립트를 검사하는 방식에 초점을 맞춰왔습니다.
그러나 이번 공격은 native Node.js 모듈 빌드에 정상적으로 사용되는 binding.gyp 파일을 악용해, node-gyp 빌드 타임에 악성 페이로드를 실행시킵니다.
패키지가 외형상 완전히 정상으로 보이더라도 설치 즉시 자격 증명 탈취가 시작될 수 있다는 의미입니다.
공격자는 탈취한 npm 토큰, GitHub 토큰, 클라우드 자격 증명을 활용해 신뢰받는 패키지의 새 버전을 직접 배포하고 공급망 전체로 악성 코드를 확산시킵니다. 이는 단순한 악성 패키지 유포를 넘어, 개발 조직이 신뢰해온 오픈소스 패키지 자체가 전파 경로가 되는 구조적 위협입니다. '과거에 안전했던 패키지'라는 신뢰만으로는 오늘의 개발 환경을 지킬 수 없습니다.
*아래 글은 소나타입(Sonatype)의 공식 블로그 글을 번역하여 작성되었습니다.
요약
- Sonatype 보안 연구팀은 package.json 의 사전 설치 및 사후 설치 스크립트를 넘어선 281개(2026년 6월 5일 기준, 304개로 증가) 의 악성 npm 패키지 버전으로 구성된 새로운 Shai-Hulud Miasma 공격을 추적하고 있습니다 .
- 이 변종은 binding.gyp를 악용하여 npm install 중에 node-gyp를 통해 실행을 트리거하고 , 개발자 및 CI/CD 데이터를 수집하고, 자격 증명을 탈취하고, 접근 권한을 검증하고, 자체적으로 확산될 수 있습니다.
- 영향을 받는 버전을 설치한 조직은 해당 환경을 잠재적으로 손상된 환경으로 간주하고, 자격 증명을 주기적으로 변경하고, 패키지 아티팩트를 확인하고, 후속 활동을 조사해야 합니다.
Shai-Hulud가 npm 생태계 전반에 걸쳐 281개의 악성 패키지 버전을 배포하는 캠페인을 다시 시작했습니다.
이번 공격은 "Miasma: The Spreading Blight"라는 캠페인의 일환으로, 오픈 소스 패키지에 대한 신뢰를 악용하여 소프트웨어 공급망을 통해 확산되는 것을 목표로 합니다.
이번 공격이 주목할 만한 이유는 실행 방식의 변화 때문입니다. 기존에는 package.json 파일 의 사전 설치 또는 사후 설치 스크립트 에만 의존했지만 , 이번 변종은 Node.js 네이티브 애드온을 사용하는 패키지에서 흔히 사용되는 binding.gyp 파일을 악용합니다. 공격자는 데이터와 자격 증명을 수집한 후, 권한이 허용되면 정식 패키지의 악성 버전을 배포합니다.
영향을 받는 버전을 설치한 조직은 해당 환경을 잠재적으로 손상된 환경으로 간주해야 합니다. 패키지를 제거하는 것이 권장되지만, 자격 증명이 노출되었거나 후속 활동이 발생한 경우에는 그것만으로는 충분하지 않을 수 있습니다.
소나타입은 Sonatype Guide und er sonatype-2026-003581 을 통해 이 캠페인을 추적하고 있습니다 .
이번 공격에서 실제로 무슨 일이 있었나
Shai-Hulud 캠페인이 악성 install-time 동작을 포함하도록 변조된 npm 패키지에 영향을 미치는 새로운 Miasma 웨이브로 재등장했다.
실행 후 해당 악성코드는 다음과 같이 동작한다:
- 시스템, 사용자, 개발자 설정, CI/CD 환경 데이터를 수집한다.
- GitHub 액세스 토큰, 패키지 레지스트리 인증 토큰, 클라우드 관련 시크릿을 탐색한다.
- 탈취한 자격 증명을 검증하고 접근 가능한 리포지토리, 서비스, 권한 수준을 열거한다.
- 탈취한 메인테이너 자격 증명을 사용해 악성 패키지 아티팩트를 생성하고 배포한다.
이 배포 기능을 통해 공격자는 정상 패키지의 새로운 악성 버전을 push하고, 침해된 리포지토리, CI/CD 환경, 패키지 레지스트리를 통해 더 넓게 전파할 수 있다.
이는 단순한 자격 증명 탈취가 아니다. 신뢰받는 개발 관계를 전파 경로로 활용하는 스스로 확산되는 공급망 공격이다.
binding.gyp 악용이 탐지를 어렵게 만드는 이유
대부분의 npm 악성코드 가이드는 개발자와 보안팀에게 package.json의 preinstall, install, postinstall과 같은 수상한 라이프사이클 스크립트를 살펴보도록 훈련시켜왔다.
그것은 여전히 중요하지만, 이번 캠페인은 그것만으로는 충분하지 않음을 보여준다.
관찰된 Miasma 변종에서 악성 패키지는 설치 중 node-gyp rebuild가 실행되도록 하는 작은 binding.gyp 파일을 포함할 수 있다. node-gyp는 native Node.js 애드온 컴파일에 사용되는 정상적인 빌드 도구이므로, 단독으로 봤을 때 즉각적으로 수상해 보이지 않을 수 있다.
악성 동작은 binding.gyp 설정 내의 명령 실행을 악용하는 방식으로 이루어진다. 정상적인 native 확장 기능을 컴파일하는 대신, 해당 설정이 패키지 설치 과정 중 악성 JavaScript 페이로드를 실행할 수 있다.
그 결과 다음과 같은 은밀한 실행 경로가 만들어진다:
- 개발자 또는 CI 작업이 정상적인 npm 패키지 버전처럼 보이는 것을 설치한다.
- npm이 binding.gyp를 감지하고 node-gyp rebuild를 호출한다.
- 악성 binding.gyp가 페이로드를 실행한다.
- 애플리케이션이 패키지를 import하기도 전에 페이로드가 실행된다.
- package.json 라이프사이클 스크립트만 검사하는 보안 도구는 이 동작을 놓칠 수 있다.
이것이 이번 캠페인의 핵심 교훈이다: install-time 리스크는 install 스크립트보다 더 광범위하다.
패키지는 메타데이터 수준에서 정상으로 보이면서도 설치 중 코드를 실행할 수 있다.
신뢰받는 패키지가 공격의 전달 수단이 되다
이번 캠페인은 중요한 사실을 다시 한번 상기시킨다.
공격자는 개발자가 이미 신뢰하는 패키지를 침해할 수 있다면, 명백히 수상한 패키지를 설치하도록 설득할 필요가 없다.
현대 소프트웨어 팀은 다음과 같은 신뢰 신호에 크게 의존한다. 익숙한 패키지 이름, 정상적인 메인테이너, 알려진 네임스페이스, 이력상 다운로드 수, 또는 내부 카탈로그에서의 사전 승인 여부. 이러한 신호는 유용하지만 충분하지 않다.
패키지는 월요일에 안전했다가 화요일에 침해될 수 있다. 메인테이너 계정은 토큰이 탈취되기 전까지는 신뢰할 수 있다. 패키지 버전은 정상적인 레지스트리에서 제공되면서도 악성 코드를 포함할 수 있다.
그것이 공격자의 이점이다. 바로 가정된 신뢰다. 소프트웨어 팀은 인간이 현실적으로 수동으로 관리할 수 있는 것보다 더 빠르게 더 많은 신뢰 결정을 내리고 있다. 개발자들은 생성된 코드를 수락하고, 의존성을 추가하고, 패키지를 업데이트하고, 전통적인 검토 모델이 따라갈 수 있는 속도를 넘어서는 자동화 파이프라인을 통해 배포한다.
속도가 문제가 아니다. 관리/통제되지 않는 신뢰가 문제다.
우리 조직이 영향을 받았는지 확인하는 방법
조직은 개발자 환경, CI/CD 파이프라인, 빌드 컨테이너 또는 프로덕션 인접 시스템에 영향을 받은 패키지 버전이 설치되었는지 조사해야 한다.
다음 항목을 검토하는 것부터 시작한다:
- 의존성 및 lockfile: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, 빌드 매니페스트, 컨테이너 이미지에서 영향을 받은 패키지를 검색한다. 악성 버전이 제한된 기간 동안만 제공된 경우, lockfile과 패키지 캐시가 가장 좋은 증거가 될 수 있다.
- CI/CD 로그: 수상한 install-time 동작을 확인한다. 예상치 못한 node-gyp rebuild 활동, 크거나 난독화된 JavaScript 파일, 의존성 설치 중 Bun 다운로드, 정상적인 패키지 설치와 일치하지 않는 외부 연결 등이 포함된다.
- 리포지토리 설정: Claude Code, Cursor, Gemini, VS Code, GitHub 워크플로우 관련 파일을 포함한 예상치 못한 AI 어시스턴트 또는 IDE 설정 변경을 확인한다.
악성코드가 자격 증명을 타깃으로 하기 때문에, 설치가 확인된 경우 해당 환경이 실행된 환경의 잠재적 침해로 간주해야 한다.
악성 버전이 다운로드되었다면? > 침해를 가정하고 조치하라
조직이 영향을 받은 버전을 설치했다면, 해당 환경이 침해되었다고 가정하고 즉시 자격 증명 교체를 시작해야 한다.
npm 토큰, GitHub 토큰, GitHub Actions 자격 증명, 클라우드 공급자 자격 증명, 패키지 레지스트리 자격 증명, SSH 키, 그리고 영향을 받은 개발자 머신이나 CI/CD 러너에서 접근 가능한 모든 시크릿을 우선적으로 처리한다. GitHub, npm, 클라우드 감사 로그에서 예상치 못한 리포지토리 접근, 패키지 배포, 워크플로우 변경, 토큰 사용, 또는 새로 생성된 리포지토리를 확인한다.
다음으로, 영향을 받은 패키지 버전을 제거하고 애플리케이션과 빌드 프로세스가 침해되지 않은 버전을 사용하도록 조치한다. 이 공격은 정상 패키지의 침해된 버전을 포함하기 때문에, 단순히 패키지 이름을 승인하는 것만으로는 충분하지 않다. 팀은 정확한 버전과 아티팩트를 검증해야 한다.
또한 보안팀은 다음 디렉토리를 특히 주의하여 예상치 못한 커밋이나 설정 파일이 없는지 리포지토리를 감사해야 한다:
- .github/
- .claude/
- .cursor/
- .gemini/
- .vscode/
수상한 변경 사항이 발견된 경우 해당 사항을 제거하고 무단 활동에 대한 커밋 이력을 검토한다.
마지막으로, 패키지 배포 자격 증명이 노출되었는지 여부를 조사한다. 공격자가 메인테이너 수준의 접근 권한을 얻은 경우, 로컬 정리에 그치지 않고 다운스트림 패키지 무결성 검토를 포함한 대응이 필요하다.
쿨다운 기간은 단지 임시방편
빠르게 움직이는 npm 침해에 대한 실용적인 방어 수단 중 하나는 새로 게시된 패키지 버전에 대한 쿨다운 기간을 두는 것이다.
새 버전을 검토 보류 상태로 두거나 악성 패키지가 식별될 시간을 확보함으로써 게시 직후 발견되는 공격에 대한 노출을 줄일 수 있다.
쿨다운 기간과 기타 시간 기반 대응책은 어느 정도 도움이 된다. 그러나 신뢰받는 오픈소스 프로젝트를 침해하고 정상적인 패키지 워크플로우를 활용해 전파하는 캠페인에 대한 완전한 방어책은 아니다.
더 근본적인 문제는 구조적인 측면이다. 조직은 오픈소스 동작, 패키지 무결성, 메인테이너 위험, install-time 활동에 대한 지속적인 가시성이 필요하다. 단순히 패키지가 과거에 승인되었는지 여부뿐만 아니라, 오늘 출시되는 특정 버전에서 악의적인 활동의 징후가 보이는지 여부까지 평가해야 한다.
즉 보안 프로그램은 오픈소스 소프트웨어가 개발 및 빌드 환경에 도입될 때마다 지속적으로 감사를 실시해야 한다.
또한 코딩 어시스턴트가 의존성을 추천하거나, 패키지 설치 명령을 생성하거나, 리포지토리 설정과 상호작용할 수 있는 AI 지원 개발 워크플로우도 고려해야 한다.
거버넌스 자동화 없이는 다음 공격을 막을 수 없다
다음 공급망 공격의 물결은 분기별 정책 검토를 기다려주지 않을 것이다. 신뢰받는 오픈소스 프로젝트은 더욱 조직적인 공격의 일환으로 장악되고 있다. Install-time 실행 경로는 확장되고 있다. 자격 증명 탈취가 전파를 가속화하고 있다.
AI 시대의 개발 워크플로우는 악성 설정/구성이 숨을 수 있는 새로운 공간을 만들어내고 있다.
조직은 어제의 신뢰 결정에 의존해 오늘의 빌드/개발 환경을 보호할 수 없다.
새로운 패키지 버전이 출시될 때마다 새로운 위험 요소에 대한 결정을 내려야 할 시기가 도래한 것이다.
출처
소나타입 블로그 : New Shai-Hulud Miasma Wave Hits Hundreds of npm Packages
'Security Insights & Trends' 카테고리의 다른 글
| 방치된 오픈소스 패키지 노린 Atomic Arch 공급망 공격 주의보 (0) | 2026.06.18 |
|---|---|
| [탈클라우드 시대 4편] 하이브리드 인프라의 미래: 홈랩 경험이 만드는 차세대 클라우드 전문가 (0) | 2026.05.29 |
| AI 취약점 폭풍의 서막, Claude Mythos와 소프트웨어 공급망 보안의 진화 (0) | 2026.05.27 |
| [탈클라우드 시대 3편] 홈서버 제로 트러스트: 포트포워딩의 위험성과 Cloudflare 방어 전략 (0) | 2026.05.22 |
| [탈클라우드 시대 2편] 프라이빗 AI 아키텍처: 로컬 LLM과 Tailscale 초연결 생태계 (0) | 2026.05.13 |