Issue
npm 400개 패키지가 털렸다 — Mini Shai-Hulud 웜과 AI 코딩 도구 하이재킹 (대안까지)
2026년 8월 npm 공급망 공격. keyv 유지보수자 계정 탈취로 시작해 400+ 패키지 감염. 설치 시 preinstall로 자동 실행, Claude Code/VS Code/Codex 하이재킹. 영향 20억+ 월간 설치. pnpm v11·npm v12·--ignore-scripts 같은 실질적 대안 포함.

핵심 요약
- 2026년 8월, npm 생태계에서 400개 이상 패키지(SafeDep 추적 기준 444개 패키지명·2,234개 poisoned 버전)가 감염된 공급망 공격 발생 — Mini Shai-Hulud 자가복제 웜
- keyv 유지보수자 GitHub 계정 탈취로 시작, 훔친 npm 발행 토큰으로 웜이 스스로 다른 패키지에 재발행하며 확산 (1차 감염 → 400+ 패키지 2차 감염)
- 영향 규모: keyv(약 127M/주), flat-cache(565M/월), file-entry-cache(557M/월) 등 — ESLint 하위 의존성이라 대부분 팀이 전이적으로 노출 (총 20억+ 월간 설치 수준)
- 설치 시
preinstall훅으로 자동 실행 + Bun 런타임을 공식 GitHub URL에서 받아 의심 도메인 없이 동작 - AI 코딩 도구 하이재킹이 특징:
.claude/,.vscode/, CodexSessionStart에 지속성 주입 → 설치 후에도 AI 세션 열 때마다 재실행 - 대안 존재: pnpm v11 / npm v12(설치 스크립트 기본 OFF) 전환,
--ignore-scripts, 자동 패치 업그레이드 중단
1. 무슨 일이 벌어졌나 — 캠페인 타임라인
| 날짜 | 사건 | 출처 |
|---|---|---|
| 8/4 | keyv 유지보수자 GitHub 계정 탈취 → 악성 릴리즈 발행 | Microsoft·Wiz·Aikido·Unit42 |
| 8/4 | npm이 악성 버전 un-publish + clean 버전 복원 | Aikido·Phoenix |
| 8/6 | 감염 400+ 패키지로 확산 확인 | Microsoft 블로그 |
| 8/10~11 | SafeDep이 444개 패키지명·2,234개 poisoned 버전 추적 | SafeDep |
Microsoft Threat Intelligence가 이 캠페인을 "ChainDrop" 이라 명명하며 공개 분석했다.
2. 영향 규모 — 왜 이렇게 위험한가
| 패키지 | 월간 다운로드 | 악성 버전 |
|---|---|---|
| keyv | ~127M/주 (604M/월) | 6.0.0 |
| flat-cache | ~565M/월 | 6.1.24 |
| file-entry-cache | ~557M/월 | (확인 필요) |
| cacheable | 30M/월 | 2.5.1 |
| cache-manager | 16M/월 | 7.2.10 |
| @cacheable/node-cache | 6M/월 | 3.1.2 |
가장 위험한 지점: flat-cache·file-entry-cache는 ESLint의 하위 의존성이다. 즉 "난 ESLint만 쓴다"고 생각해도 이 악성 패키지에 전이적으로 노출될 수 있다. 규모가 20억+ 월간 설치에 달하는 이유다.
3. 공격 체인 — 어떻게 동작했나
npm install
→ preinstall 훅 (package.json에 주입)
→ setup.mjs 실행 (난독화 dropper, 728KB)
→ Bun 런타임 다운로드 (github.com/oven-sh/bun 공식 릴리즈 URL)
→ Math_Symbol.js / Math_Init.js 실행 (실제 페이로드)
핵심 우회 2가지:
- 유효한 OIDC provenance로 발행 — 악성 파일을 main 브랜치에 직접 푸시 + 즉시 릴리즈 → "정당한 CI 워크플로에서 발행됨"으로 npm provenance 검증을 우회. 즉 "서명됐다"는 게 안전을 보장하지 않음을 증명.
- 의심 도메인 없는 런타임 우회 — 공식 GitHub URL에서 Bun을 받으므로 egress 모니터링·레포테이션 검사가 걸리지 않음.
4. 무엇을 훔치나 — 자격증명 수집
| 대상 | 수집 경로 |
|---|---|
| npm 토큰 | ~/.npmrc + 파일시스템 스캔, 실시간 whoami 검증 후 유출 |
| GitHub 토큰 | ~/.config/gh/hosts.yml, 환경변수, OIDC 토큰(ACTIONS_ID_TOKEN_REQUEST_*) |
| 클라우드 | AWS 키, Kubernetes SA 토큰, DB 연결문자열 |
| 기타 | PEM·SSH 키, HashiCorp Vault(VAULT_TOKEN), 5MB 초과 파일 스킵 |
유출은 AES-256-GCM 암호화 + RSA 키로 감싸 t.m-kosche[.]com(OpenTelemetry 위장), npm-cache[.]com 등으로 전송. GitHub 토큰은 이중 Base64 인코딩. 주 채널 차단 시 "Shai-Hulud: Here We Go Again" 설명을 단 공개 GitHub 저장소에 결과 업로드.
C2 백도어(SafeDep): kitty-monitor — GitHub 커밋 검색 API를 매시간 폴링, 커밋 메시지 firedalazer 키워드로 RSA-PSS 서명된 명령 수신 → 임의 Python 실행.
5. AI 코딩 도구 하이재킹 — 이번 공격의 가장 큰 특징
기존 공급망 공격이 "설치하면 끝"이었다면, 이 공격은 설치 후에도 지속된다:
- Claude Code:
.claude/settings.json,.claude/setup.mjs주입 - VS Code:
.vscode/tasks.json,.vscode/setup.mjs주입 - Codex:
SessionStart훅 주입 (SafeDep 확인) - CI:
.github/workflows/codeql.yml에 지속성 주입
의미: 개발자가 나중에 그 레포에서 Claude Code/VS Code/Codex 세션을 열 때마다 페이로드가 재실행된다. npm install과 무관하게, 코딩 도구 자체가 감염 경로가 된다.
또한 revoked 토큰 감시 장치 — 훔친 GitHub 토큰이 폐기되면 파괴 핸들러가 발동, 대응 순서를 뒤집는다 (Phoenix Security 강조).
6. 대응 상태
- npm: 악성 버전 un-publish,
latest→ clean 버전 복원 ([email protected],[email protected],[email protected]) - ⚠️ Chainguard 경고: "소스 저장소는 clean 버전 복원 후에도 여전히 오염(persisted) — 핀된 버전은 임시 수정일 뿐"
- Microsoft Defender:
Trojan:npm/MalBun.A탐지 - CVE 미할당 (공급망 특성)
7. 대안 — 패키지 매니저 수준 (실질적 해법)
핵심 문제는 "npm CLI가 설치 스크립트를 기본 실행 + 소비자 측 방어 없음". 이를 해결하는 패키지 매니저 대안이 있다 (Mondoo 보안 연구 비교):
| 기능 | pnpm v11 | Yarn Berry v4 | Bun | npm CLI |
|---|---|---|---|---|
| 스크립트 차단(기본) | ✅ 기본 | ✅ | ✅ | ❌ |
| 이상 하위의존성 차단 | ✅ 기본 | 부분 | ❌ | ❌ |
| 릴리즈 쿨다운 | ✅ 기본 | — | — | ❌ |
pnpm v11이 소비자 측 방어가 가장 강력하다 — 기본 스크립트 차단(Shai-Hulud 1단계 차단), 릴리즈 쿨다운(악성 패치 창 축소), 이상 하위의존성 차단. npm CLI는 유일하게 소비자 측 방어가 없는 매니저다.
npm CLI를 유지해야 한다면:
- ✅ npm v12로 업그레이드 — 2026-07 출시, 설치 스크립트 기본 OFF + 2FA 우회 토큰(GAT) 폐기 시작
npm install --ignore-scripts(OWASP 권장)npm ci(lockfile 정확 준수) + 정확한 버전 pin (--save-exact)npm audit signatures(provenance 검증)
추가 도구:
- Verdaccio — 사내 npm 프록시 (승인된 패키지만 통과)
- Socket safe-npm —
npm install래핑, 설치 전 위험 차단 (alias npm="socket npm") - Dependabot + CodeQL — 알려진 취약점 자동 감지
8. 실무 체크리스트
npm ls로 영향 버전 확인 (전이 의존성 포함)- 영향 버전이면 검증된 clean 버전으로 다운그레이드
.npmrc·gh 토큰·SSH 키 즉시 교체(유출 가정) + 2FA- pnpm 전환 또는 npm v12 업그레이드
- 자동 패치 업그레이드 중단 — 대부분의 npm 해킹은 패치 자동 승격으로 전파됨
- GitHub Actions에서 불필요한 시크릿·
id-token: write제거 .claude/,.vscode/,.github/workflows/codeql.yml변경 감시
판단
이번 공격이 보여주는 가장 위험한 진실 두 가지:
- OIDC provenance 우회 — "정당한 서명으로 발행됐다"는 게 안전을 보장하지 않는다. provenance 검증이 만능이 아님을 실증.
- AI 도구 하이재킹 — Claude Code/Codex/VS Code를 직접 노려 "설치 후에도 세션마다 재실행". AI 코딩 에이전트를 쓰는 모든 개발자에게 직접적인 경고.
해법은 있다. pnpm 전환 + --ignore-scripts + 자동 패치 업그레이드 중단이라는 즉효 대안이 존재한다. 단순한 "방어 체크리스트"가 아니라 패키지 매니저 자체를 바꾸는 것이 근본 해결이다.
표본 한계
- 감염된 실제 머신 수는 어느 보안 기관도 공개 못 함 (버전 해석·lifecycle 스크립트 실행 여부에 의존)
- 다중 소스(Microsoft, Wiz, Aikido, Unit42, DataDog, SafeDep, Phoenix) 교차 검증 — 다만 각 기관 수치(패키지 수·다운로드)가 소폭 상이
- 대안 비교(pnpm v11 등)는 공급사(Mondoo) 자료 기준