
또 npm이 뚫렸습니다
자바스크립트 생태계를 쓰는 분이라면 한 번쯤 들어봤을 거예요. npm 저장소에서 또 대규모 공급망 공격이 터졌습니다. 이번에 발견된 공격은 'Mini Shai-Hulud'라는 이름이 붙었는데요. 무려 314개의 npm 패키지가 한꺼번에 감염됐어요. 'Shai-Hulud'는 작년에 한 번 크게 화제가 됐던 npm 웜의 이름이에요. 듄(Dune) 영화에 나오는 거대한 모래벌레 이름에서 따왔죠. 그때 그 공격의 변종이라서 '미니'라는 수식어가 붙은 겁니다.
공급망 공격이 뭐냐면, 우리가 직접 쓰는 라이브러리 자체를 공격하는 게 아니라, 그 라이브러리가 의존하는 또 다른 패키지를 노리는 방식이에요. 예를 들어 여러분이 만든 앱이 A라는 라이브러리를 쓰고, A는 B를 쓰고, B는 C를 쓴다고 해봅시다. 공격자가 C를 감염시키면, 그 위에 올라간 A, B, 그리고 여러분의 앱까지 다 영향을 받아요. 이런 식의 연쇄 감염이 npm 생태계에서 특히 무서운 이유는, 자바스크립트 프로젝트 하나가 보통 수백, 수천 개의 간접 의존성을 가지고 있기 때문입니다.
어떻게 감염시켰을까
이번 공격의 메커니즘이 좀 영리합니다. 공격자는 먼저 npm 메인테이너(패키지 관리자)들의 계정을 탈취해요. 주로 피싱 메일을 보내서 npm 로그인 토큰을 빼내는 방식이죠. 토큰만 손에 넣으면 그 사람 명의로 패키지에 악성 코드를 박은 새 버전을 올릴 수 있게 됩니다.
그렇게 올라간 악성 코드는 postinstall 스크립트라는 npm의 기능을 활용해요. 이게 뭐냐면, 패키지를 설치할 때 자동으로 실행되는 스크립트입니다. 원래는 컴파일이나 환경 설정 같은 정상적인 용도로 쓰라고 만든 기능인데, 공격자 입장에선 "설치만 해도 내 코드가 실행되는" 황금 열쇠인 셈이죠. npm install 한 번에 사용자의 시스템에서 코드가 돌아갑니다.
실행된 악성 코드는 보통 이런 일을 해요. 환경 변수에 있는 AWS, GCP 키나 GitHub 토큰을 긁어모으고, .npmrc나 ~/.aws/credentials 같은 민감한 파일을 읽어서 외부 서버로 전송합니다. 더 무서운 건 자기 자신을 다른 패키지로 퍼뜨리는 웜(worm) 동작인데요. 훔친 npm 토큰으로 그 메인테이너가 가진 다른 패키지에도 똑같이 악성 코드를 심어버립니다. 이래서 한 번 시작되면 기하급수적으로 퍼져요. 이번 314개라는 숫자도 이런 자가 증식의 결과입니다.
작년 Shai-Hulud와 뭐가 다른가
작년 원본 Shai-Hulud는 GitHub Actions까지 건드리는 좀 더 정교한 공격이었어요. 감염된 패키지가 설치되면 사용자의 GitHub에 새 워크플로 파일을 만들어서, 시크릿을 빼내는 식이었거든요. 이번 '미니' 버전은 그 정도까진 아니고, 주로 npm 토큰 탈취와 자가 전파에 집중합니다. 그래서 '미니'라는 표현이 붙은 건데, 그렇다고 위협이 작다는 뜻은 아닙니다. 오히려 단순화돼서 더 빨리 퍼지는 측면이 있어요.
비슷한 사례는 작년에 있었던 event-stream 사건, 그리고 ua-parser-js 사건도 떠올려볼 만해요. 매번 패턴은 비슷합니다. 인기 있는 패키지의 메인테이너 계정을 노린다, postinstall로 자동 실행시킨다, 자격증명을 빼낸다. npm 측에서는 2FA 의무화를 점점 확대하고 있지만, 모든 패키지 메인테이너가 보안에 신경 쓰는 건 아니라서 빈틈이 계속 생기는 거예요.
우리는 뭘 해야 할까
한국 개발자분들이 당장 할 수 있는 일을 정리해볼게요. 첫째, package-lock.json이나 pnpm-lock.yaml을 반드시 커밋해서 의존성 버전을 고정하세요. 둘째, CI 환경에서는 npm ci --ignore-scripts 옵션을 써서 postinstall 스크립트 자체를 차단하는 걸 고려해보세요. 빌드가 깨지는 패키지도 있겠지만, 그건 별도로 처리하면 됩니다. 셋째, npm audit이나 socket.dev, snyk 같은 도구로 정기적으로 의존성을 스캔하세요.
특히 회사 코드를 다루는 분이라면 CI/CD 파이프라인에 박혀 있는 토큰들을 점검해보세요. AWS 키, GitHub PAT, npm publish 토큰 같은 것들이요. 이번 공격에서 가장 큰 피해는 코드 자체보다 이런 자격증명 유출이거든요. 한 번 유출되면 사고가 어디까지 번질지 가늠하기 어렵습니다.
마무리
오픈소스 생태계의 신뢰는 결국 메인테이너 한 명 한 명의 보안 위생에 달려 있어요. 그런데 그 메인테이너들 대부분이 자원봉사자라는 게 이 시스템의 근본적인 모순입니다. 여러분은 자신의 프로젝트에서 의존성을 얼마나 자주 감사하시나요? 그리고 postinstall 스크립트를 모두 차단하는 정책, 도입해볼 만하다고 생각하시나요?
🔗 출처: Hacker News
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공