npm 400개 패키지가 털렸다 — Mini Shai-Hulud 웜과 AI 코딩 도구 하이재킹 (대안까지)

2026년 8월 npm 공급망 공격. keyv 유지보수자 계정 탈취로 시작해 400+ 패키지 감염. 설치 시 preinstall로 자동 실행, Claude Code/VS Code/Codex 하이재킹. 영향 20억+ 월간 설치. pnpm v11·npm v12·--ignore-scripts 같은 실질적 대안 포함.

npm 400개 패키지가 털렸다 — Mini Shai-Hulud 웜과 AI 코딩 도구 하이재킹 (대안까지) 대표 이미지

핵심 요약

  • 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/, Codex SessionStart에 지속성 주입 → 설치 후에도 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가지:

  1. 유효한 OIDC provenance로 발행 — 악성 파일을 main 브랜치에 직접 푸시 + 즉시 릴리즈 → "정당한 CI 워크플로에서 발행됨"으로 npm provenance 검증을 우회. 즉 "서명됐다"는 게 안전을 보장하지 않음을 증명.
  2. 의심 도메인 없는 런타임 우회 — 공식 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. 실무 체크리스트

  1. npm ls로 영향 버전 확인 (전이 의존성 포함)
  2. 영향 버전이면 검증된 clean 버전으로 다운그레이드
  3. .npmrc·gh 토큰·SSH 키 즉시 교체(유출 가정) + 2FA
  4. pnpm 전환 또는 npm v12 업그레이드
  5. 자동 패치 업그레이드 중단 — 대부분의 npm 해킹은 패치 자동 승격으로 전파됨
  6. GitHub Actions에서 불필요한 시크릿·id-token: write 제거
  7. .claude/, .vscode/, .github/workflows/codeql.yml 변경 감시

판단

이번 공격이 보여주는 가장 위험한 진실 두 가지:

  1. OIDC provenance 우회 — "정당한 서명으로 발행됐다"는 게 안전을 보장하지 않는다. provenance 검증이 만능이 아님을 실증.
  2. AI 도구 하이재킹 — Claude Code/Codex/VS Code를 직접 노려 "설치 후에도 세션마다 재실행". AI 코딩 에이전트를 쓰는 모든 개발자에게 직접적인 경고.

해법은 있다. pnpm 전환 + --ignore-scripts + 자동 패치 업그레이드 중단이라는 즉효 대안이 존재한다. 단순한 "방어 체크리스트"가 아니라 패키지 매니저 자체를 바꾸는 것이 근본 해결이다.

표본 한계

  • 감염된 실제 머신 수는 어느 보안 기관도 공개 못 함 (버전 해석·lifecycle 스크립트 실행 여부에 의존)
  • 다중 소스(Microsoft, Wiz, Aikido, Unit42, DataDog, SafeDep, Phoenix) 교차 검증 — 다만 각 기관 수치(패키지 수·다운로드)가 소폭 상이
  • 대안 비교(pnpm v11 등)는 공급사(Mondoo) 자료 기준