Skip to main content
공개 노트

Mini Shai-Hulud가 드러낸 진짜 문제: 패키지 검사가 아니라 설치 실행 통제다

Views 23약 5분생성형 AI 활용
Summary

Mini Shai-Hulud가 드러낸 진짜 문제: 패키지 검사가 아니라 설치 실행 통제다

우리 팀은 이미 의존성 스캔도 하고, 버전도 잠그고, CI도 관리하는데 도대체 뭐가 더 위험할까. Mini Shai-Hulud는 이 질문에 불편한 답을 던진다. 지금의 패키지 공격은 "나쁜 라이브러리가 들어왔다"보다 "설치 순간에 코드를 실행하게 했다"에 더 가깝다.

이번 캠페인은 SAP 관련 npm 패키지 4종을 시작으로 Intercom의 npm 패키지, PyPI의 Lightning까지 번졌고, 감염된 설치 과정에서 개발자 토큰과 CI 비밀값을 훔치고 GitHub를 경유해 퍼졌다.123 중요한 점은, 이런 공격이 많은 팀이 익숙한 취약점 관리 도구만으로는 잘 막히지 않는다는 것이다.

"우린 의존성 스캔한다"로는 부족한 이유

확인된 사실부터 보자. SAP 생태계의 mbt@1.2.48, @cap-js/sqlite@2.2.2, @cap-js/postgres@2.2.2, @cap-js/db-service@2.10.1에는 공통적으로 preinstall 훅이 추가됐고, 이 훅이 setup.mjs를 실행해 Bun 런타임을 내려받은 뒤 대형 난독화 페이로드를 돌렸다.45 즉, 문제의 핵심은 애플리케이션 코드가 아니라 npm install 자체였다.

이 차이는 실무에서 크다. SBOM, 취약점 DB, 버전 핀ning, lockfile은 "무엇을 받았는지"를 잘 보여준다. 하지만 이번 유형은 "받는 순간 무엇이 실행됐는지"가 본질이다. 정상 패키지 파일을 대부분 그대로 두고, 설치 훅만 끼워 넣어도 공격은 성립한다.4

더 나쁜 점은 실행 경계가 넓어졌다는 것이다. 이 악성코드는 Bun을 별도로 받아 실행했고, 일부 분석에 따르면 GitHub Actions 러너 메모리에서 비밀값을 추출하려 시도했다.45 다시 말해 Node 생태계를 본다고 안심할 수 없다. 설치 중에 다른 런타임, 다른 프로세스, 다른 네트워크 호출이 튀어나올 수 있다.

강해 보이는 방어와, 실제로 끊어내는 방어는 다르다

여기서 흔한 반론이 있다. "lockfile 있으면 괜찮지 않나?" 부분적으로만 맞다. 이미 악성 버전이 lockfile에 들어갔다면 오히려 재현성 있게 계속 설치된다. 반대로 lockfile이 없다면 더 쉽게 오염된다. lockfile은 중요하지만, 실행 자체를 막는 장치는 아니다.

비슷하게 취약점 스캐너도 사후 가시성에는 도움이 되지만, 이런 사건은 CVE나 GHSA가 없던 시점에 진행됐다.6 즉 "알려진 취약점" 중심 운영은 여기서 한 박자 늦다.

이번 공격을 실제로 끊는 쪽에 더 가까운 통제는 따로 있다.

첫째, 설치 스크립트 차단이다. npm install --ignore-scripts 같은 기본 정책은 마찰이 있지만, 최소한 CI의 기본값으로 검토할 가치가 커졌다. 물론 네이티브 모듈이나 합법적 postinstall이 깨질 수 있다는 트레이드오프가 있다. 그래서 전면 금지보다 "기본 차단 + 허용 목록"이 현실적이다.

둘째, 설치 환경 격리다. 일회성 CI 러너, 최소 권한 토큰, 개발자 로컬과 배포 자격증명의 분리, 설치 단계의 네트워크 이그레스 제한이 더 직접적이다. GitHub나 npm 토큰이 있더라도 패키지 설치 컨텍스트에서 새 저장소 생성, 임의 외부 다운로드, 클라우드 메타데이터 접근이 막히면 피해 폭이 줄어든다.45

셋째, 내부 미러나 승인된 레지스트리 경유다. 완벽한 방어는 아니지만, 공개 레지스트리에서 막 올라온 버전을 곧바로 개발자 노트북과 CI가 받아 실행하는 구조를 늦출 수 있다. 이번처럼 노출 시간이 몇 시간 안팎이어도, 그 몇 시간이 차이를 만든다.5

이제는 'npm install'을 미확인 바이너리 실행처럼 봐야 한다

Mini Shai-Hulud에서 정말 바뀐 것은 공격자의 기술만이 아니다. 팀이 패키지 설치를 보는 관점도 바뀌어야 한다. npm install은 메타데이터 동기화가 아니라 원격 코드 실행 트리거로 취급해야 한다.

실무 체크리스트를 짧게 정리하면 이렇다.

  • CI 기본 정책으로 lifecycle script 차단 가능 여부부터 점검

  • 불가피한 스크립트 실행 패키지는 허용 목록 관리

  • 설치 단계와 빌드/배포 단계의 자격증명 분리

  • 장기 npm 토큰 축소, OIDC는 저장소 전체가 아니라 브랜치·워크플로 단위로 제한

  • 개발자 로컬 설치를 dev container나 격리된 환경으로 유도

  • 설치 중 외부 바이너리 다운로드, GitHub 저장소 생성, 비정상 프로세스 실행 모니터링

  • 이번에 거론된 버전 설치 이력이 있으면 npm만이 아니라 GitHub, 클라우드, Kubernetes, CI 비밀값까지 회전 검토46

The Register가 정리했듯 이 캠페인은 SAP 패키지에 그치지 않고 Intercom과 Lightning까지 이어졌다.1 그래서 이 사건을 "특정 벤더 사고"로 보면 놓친다. 지금 신경 써야 할 사람은 SAP를 쓰는 팀만이 아니다. npm, PyPI, CI, 개발자 노트북이 한 흐름으로 이어진 조직이라면, 패키지 보안의 기준을 "무슨 버전을 쓰는가"에서 "설치 시 무엇을 실행하게 두는가"로 옮겨야 한다.

참고

1Experts say supply chain attacks compromised SAP and Intercom npm packages, plus the PyPI package Lightning, in a campaign that calls itself Mini Shai-Hulud (Jessica Lyons/The Register)

21,800 Hit in Mini Shai-Hulud Attack on SAP, Lightning, Intercom

3PyTorch Lightning and Intercom-client Hit in Supply Chain Attacks to Steal Credentials

4A Mini Shai-Hulud Has Appeared: Obfuscated Bun Runtime Payloads Hit SAP-Related npm Packages

5Mini Shai-Hulud Targets SAP npm Packages With a Bun-Based Secret Stealer

6Mini Shai-Hulud: Multi-Ecosystem Developer Supply Chain Attack - Lab Space

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기