Post

[Security] axios npm 패키지에 숨은 RAT, 공급망 공격 사건 정리

[Security] axios npm 패키지에 숨은 RAT, 공급망 공격 사건 정리

서론

npm install axios 한 줄. 너무 자연스럽게 치는 바람에 그 한 줄의 위험을 잊기 쉽다. 그런데 2026년 3월 31일, 이 당연한 한 줄이 RAT(원격 접근 트로이목마) 설치 한 줄이 될 뻔했다. 북한 연계 공격자가 주간 다운로드 7천만 건 규모의 axios 패키지 레지스트리에 악성 버전을 올린 사건이 터졌기 때문이다. 공급망 공격이 더 이상 “특수한 이슈”가 아닌 이유를 체감하게 해준 사건으로, 보안 커뮤니티 전반이 술렁였다. Node.js 기반 서비스가 널리 깔린 국내외 개발 조직 전반에 경각심을 일으킨 사건이기도 하다. 단순한 요약이 아니라 실무 엔지니어가 같은 일이 벌어졌을 때 어떻게 움직여야 하는지까지, 업계에서 나온 권고를 중심으로 풀어보자. 주니어 백엔드라면 이 사건 이후 변화한 보안 감수성이 어느 정도인지 체감하는 데 도움이 될 것이다.

본론

사실 관계부터 짚자. The Hacker News와 Data Breaches Digest 보도에 따르면 2026년 3월 31일 npm 레지스트리에 두 개의 악성 axios 버전이 배포됐다. 공격자는 북한과 연계된 위협 그룹으로 파악됐고, 문제 버전을 설치하면 주입된 의존성이 RAT 페이로드를 내려받는 구조였다. axios는 주간 다운로드 7천만 건 규모의 사실상 표준 HTTP 클라이언트라, 영향을 받을 수 있는 조직 수가 상상 이상으로 컸다는 점에서 파급력이 남달랐다. 과거에도 event-stream(2018), ua-parser-js(2021), node-ipc(2022) 같은 공급망 공격이 있었지만, axios는 이들보다 훨씬 더 깊이 박혀 있는 기반 라이브러리라는 점에서 경각심이 훨씬 크다는 것이 보안 전문가들의 공통된 평이다.

많은 사람이 오해하는 지점이 있다. “내가 직접 악성 코드를 쓰지 않았으니 내 프로젝트는 괜찮겠지”라는 안일함이다. 실제로는 서비스의 package-lock.json이 자동으로 업데이트되는 순간, 그 사이에 악성 버전이 물릴 수 있다는 경고가 보안 블로그 전반에서 반복된다. 특히 ^1.x.x처럼 범위 버전으로 지정된 경우, 새로 게시된 마이너 버전이 npm install만 돌려도 빌드에 딸려 들어온다. The Hacker News의 후속 분석은 “사내 보안팀 일”로만 분류했던 조직일수록 이번 사건에서 대응이 늦어졌다고 지적했다. 공급망 보안은 모든 개발자의 1차 방어선이라는 메시지가 강하게 제기됐다.

업계에서 공통적으로 권장하는 대응은 이렇게 정리된다. 먼저 npm auditnpm ls axios로 의존성 트리를 확인하고, 공개된 악성 버전 번호가 포함되어 있다면 즉시 롤백한다. 다음으로 CI 환경에서 npm ci --ignore-scripts를 기본값으로 바꿔 postinstall 단계의 임의 코드 실행을 막는다. 이 옵션은 패키지의 install 훅이 실행되지 않게 하는데, 과거 공급망 공격들의 대부분이 install 훅을 악용했다는 점에서 효과적인 1차 방어선으로 꼽힌다. 가능하면 사내 private registry나 Verdaccio, JFrog Artifactory 같은 프록시로 외부 레지스트리를 한 번 감싸고, 주요 패키지의 버전을 핀으로 고정하는 관행을 정착시키라는 권고가 보안 커뮤니티와 DevSecOps 리포트에서 반복된다. 프록시를 두면 악성 버전이 공개된 즉시 내부에서 차단해, 사내 모든 프로젝트가 같은 속도로 보호받을 수 있다.

실무 체크리스트도 정리해보자. 첫째, .npmrcignore-scripts=true를 기본값으로 넣고 필요한 프로젝트에서만 명시적으로 풀어주는 정책이 여러 엔지니어링 블로그에서 레퍼런스로 제시된다. 둘째, CI에 npm audit --audit-level=high 단계를 의무로 넣어 취약점이 발견되면 빌드를 멈추는 흐름이 표준처럼 자리 잡고 있다. 셋째, package-lock.json의 resolved URL을 코드 리뷰에서 확인하는 습관을 들이라는 조언이 많다. 악성 버전은 종종 resolved URL이 평소와 다른 호스트로 바뀌어 있는데, 사람 눈으로 한 번만 훑어도 이상 징후가 보인다는 지적이다. 넷째, 사내 정책으로 “직전 24시간 내 게시된 패키지는 자동 업그레이드 대상에서 제외” 같은 Cooldown 규칙을 두는 것도 효과적이라는 평가가 나온다. 이번 axios 사건의 악성 버전도 게시 후 수 시간 내 탐지됐는데, Cooldown이 걸려 있었다면 자동 의존성 업데이트 봇을 쓰는 환경에서도 피해를 막을 수 있었을 것이라는 분석이다.

공급망 공격이 체감되지 않는 독자에게는 다른 사례를 함께 보는 것이 도움이 된다. 같은 시기 Stryker에서는 탈취된 자격증명 하나로 Microsoft Intune을 통해 약 8만 대 디바이스가 와이프됐고, University of Mississippi Medical Center에서는 Medusa 랜섬웨어로 35개 클리닉의 Epic EMR이 9일간 마비됐다. CM-Alliance와 Strobes의 월간 사건 리포트는 두 사건 모두 “외부에서 치고 들어오는 해커”가 아니라 “이미 신뢰하던 경로(자격증명·관리 도구·공개 패키지)”를 악용한 공격이었다는 공통점에 주목했다. axios 사건도 본질은 같다. “당연하게 믿는 경로”를 누군가 정조준하면 파급력이 상상 이상으로 커진다는 것이다. 이 관점을 한 번 장착하면, 팀 내 코드 리뷰에서 “왜 이 패키지를 선택했는가, 대안은 없는가, 유지보수 상태는 어떤가”를 묻는 습관이 자연스럽게 생긴다는 것이 여러 리뷰의 공통 결론이다.

한 가지 더 강조되는 주제는 “공격 이후의 커뮤니케이션”이다. 같은 사건이 사내에서 터졌다고 가정할 때, 주니어 엔지니어에게 요구되는 첫 번째 행동은 원인 분석보다 “영향 범위 지도”를 그리는 것이라는 권고가 다수 보안 플레이북에서 반복된다. 어떤 서비스가 해당 패키지를 쓰는지, 언제 설치됐는지, 노출된 환경변수·토큰이 있는지를 10~20분 안에 공유 가능한 문서로 정리하는 것이 핵심이다. 이 문서가 늦어지면 의사결정이 늦어지고, 그 사이 피해가 커진다는 지적이다. 평소에는 주인공이 아닌 주니어가 가장 빛나는 순간이 바로 이런 “정리된 전달”이라는 이야기가 보안 컨설팅 리포트에서 자주 인용된다.

또 하나 최근 커뮤니티에서 주목받는 주제는 SBOM(Software Bill of Materials)이다. OWASP Dependency-Track이나 CycloneDX 표준을 활용해 의존성 내역을 구조화하면, 특정 버전이 취약한 것으로 공개됐을 때 영향을 받는 프로젝트를 초 단위로 찾아낼 수 있다. 미국 CISA와 유럽 ENISA의 지침은 2026년 기준 SBOM을 “선택 사항이 아닌 기본 요건”으로 분류하기 시작했고, 국내 대기업 보안팀 역시 협력사 납품물에 SBOM 제출을 요구하는 사례가 늘고 있다는 관찰이 나온다. 이번 axios 사건처럼 기반 라이브러리에 구멍이 나면, SBOM의 가치는 사고가 벌어진 순간 가장 크게 체감된다는 평이 이어지고 있다.

결론

정리하면 axios npm 사건은 “우리가 매일 쓰는 도구 자체가 공격 표면”이라는 당연하면서도 자주 잊는 사실을 다시 꺼내줬다. 보안 커뮤니티에서는 Lockfile 리뷰를 PR 체크리스트에 추가하라는 제안이 여러 번 제기됐다. 한 줄의 install 명령이 어떤 코드를 내려받는지 눈으로 확인하는 습관은, 주니어 백엔드가 실무에서 가장 빨리 만들 수 있는 보안 근육이라는 평가다. 여기에 더해 사내 의존성 관리를 “한 프로젝트의 문제”가 아닌 “조직의 공통 자산”으로 보는 시야가 권장된다. private registry, 자동 audit, Cooldown 정책, SBOM, 영향 범위 공유 템플릿까지. 이 중 하나라도 자리 잡히면 다음번에 비슷한 사건이 터졌을 때 복구 시간이 분 단위로 짧아진다. 주니어 시절에 보안 감각을 기르면, 그 감각은 연차와 함께 배로 돌아오는 투자라는 사실이 이번 사건에서 재차 확인됐다. 오늘 저녁 퇴근 전 자기 프로젝트의 lock 파일을 한 번만 열어보자는 제안은, 이 사건이 남긴 가장 현실적인 숙제로 업계에서 반복 인용되고 있다.

Reference

This post is licensed under CC BY 4.0 by the author.