npm axios 공급망 공격 (2026-03-31) — 악성 버전 1.14.1·0.30.4 설치 여부 지금 확인
2026년 3월 31일 npm axios 1.14.1·0.30.4 버전이 유지 관리자 계정 탈취로 악성 버전이 배포됐다. plain-crypto-js 포스트인스톨 후크로 크로스플랫폼 RAT가 설치된다. Microsoft·Google이 북한 Sapphire Sleet/UNC1069 그룹에 귀속시켰다.
On this page (11)
2026년 4월 · 보안 소식
npm axios 공급망 공격 (2026-03-31) — 악성 버전 1.14.1·0.30.4 설치 여부 지금 확인
2026년 3월 31일, 주간 7,000만 건 이상 다운로드되는 npm 패키지 axios에 악성 버전이 배포됐다. 유지 관리자 계정이 사회공학 공격으로 탈취돼 1.14.1과 0.30.4 두 버전이 연달아 올라갔다. 내 코드가 깨끗해도 의존성이 오염되면 끝이다. 결론부터 말한다. 지금 당장 버전을 확인해야 한다.
악성 버전은 npm 레지스트리에 약 3시간 머물렀다. 그 짧은 구간에서 추정 60만 건의 설치가 발생했다는 것이 Aikido Security와 The Hacker News 분석이다. Microsoft·Google이 배후를 북한 연계 해킹 그룹 Sapphire Sleet(UNC1069)로 공동 귀속시켰다.
이 글에서는 위험 버전 확인 방법, 악성코드 동작 원리, 즉시 조치 절차를 순서대로 정리했다. CI/CD 파이프라인까지 반드시 점검해야 한다.
- 발생 시점: 2026년 3월 31일 00:21 UTC (1.14.1) / 01:00 UTC (0.30.4)
- 위험 버전:
1.14.1, 0.30.4 (안전 버전: 1.14.0, 0.30.3)- 악성 의존성:
plain-crypto-js@^4.2.1 — postinstall 훅으로 RAT 드롭- 피해 규모: 약 3시간 노출, 추정 60만 건 설치
- 타깃: macOS, Windows, Linux 크로스플랫폼
- 배후: 북한 Sapphire Sleet (MS) / UNC1069 (Google) — 공동 귀속 확인
- 조치: 안전 버전 업그레이드 + 환경변수·크리덴셜 전면 재발급
공급망 공격이 왜 위험한가
공급망 공격(supply chain attack)은 내 코드가 아니라 배포 경로 자체를 노린다. 택배 상자 안에 물건을 바꿔치기하는 것과 같다. axios처럼 사용량이 많을수록 공격자 입장에서 더 매력적인 타깃이다. 이번에도 주간 7,000만 건 이상 다운로드되는 패키지가 선택됐다.
npm 계정을 탈취하거나 패키지 권한을 악용하면 악성 버전이 조용히 올라간다. 자동화된 CI/CD 파이프라인이 이 버전을 받아 수많은 프로젝트에 설치한다. 개발자가 눈치채기 전까지 피해가 쌓인다. 이번엔 3시간 만에 60만 건이 설치됐다.
"유명 패키지라서 안전하다"는 생각이 공격자가 노리는 허점이다. 신뢰가 높을수록 의심을 덜 받는다. axios는 React, Vue, Angular 앱의 사실상 표준 HTTP 클라이언트다. 그만큼 영향 반경이 넓다.
공격 타임라인 — 3시간 만에 벌어진 일
Aikido Security, Arctic Wolf, Elastic Security Labs가 독립적으로 재구성한 타임라인은 거의 일치한다.
- 2026-03-31 00:21 UTC —
axios@1.14.1npm 배포. 기존 1.x 라인 대상. - 00:39 경과 — 공격자가 연속으로 0.x 레거시 라인에도 악성 버전 준비.
- 01:00 UTC —
axios@0.30.4배포. 1.x와 0.x 양쪽 브랜치가 같은 시점에 오염됨. - ~03:00 UTC — 보안 연구자들이 plain-crypto-js 이상 의존성을 감지. Socket.dev·Aikido에서 alert.
- ~04:00 UTC — npm에서 두 버전 모두 강제 삭제(unpublish). 노출 총 약 3시간.
- 추정 60만 건 — 노출 구간 동안 CI/CD·로컬 설치 합산 추정치.
"3시간만 올라갔으니 별거 아니다"는 오판이다. Vercel, GitHub Actions, CircleCI 같은 CI 환경은 10~30초 단위로 캐시 미스 시 최신 버전을 끌어온다. 그 3시간에 globally 수십만 빌드가 돌아간다. npm 레지스트리의 CDN 캐시가 삭제 후에도 일시적으로 악성 버전을 서빙한 사례가 여러 지역에서 보고됐다.
어떤 버전이 위험한가
문제가 된 버전은 1.14.1과 0.30.4다. 이 두 버전에는 plain-crypto-js@^4.2.1이라는 패키지가 의존성으로 딸려온다. 이 패키지가 postinstall 훅을 통해 RAT을 설치한다.
·
1.14.1 (악성) / 1.14.0 (안전)·
0.30.4 (악성) / 0.30.3 (안전)· 1.15.0 이후, 0.30.5 이후 — 안전 (공식팀 공지 버전)
정상적인 axios 릴리스에는 plain-crypto-js가 없다. 이 패키지는 axios 소스 어디에서도 import되지 않는다. 오직 postinstall 훅을 실행시키기 위해 의존성 트리에 넣어둔 것이다. 버전 번호가 익숙해 보여도 lock 파일을 직접 열어보기 전까지는 믿으면 안 된다.
1.14.0이나 1.13.x처럼 인접 버전은 영향이 없다. 하지만 npm의 범위 지정자(~, ^)로 자동 업데이트 설정이 돼 있다면 실수로 악성 버전이 설치됐을 수 있다. package.json의 버전 범위도 같이 확인해야 한다.
악성코드는 어떻게 동작하나
plain-crypto-js는 암호화 유틸리티를 가장한 악성 패키지다. 설치 과정에서 npm이 postinstall 스크립트를 자동 실행한다. 이 훅이 공격자 C2(Command & Control) 서버에 접속해서 2차 페이로드를 받아온다.
2차 페이로드는 실행 OS를 감지해서 맞는 RAT(Remote Access Trojan, 원격접근 트로이목마)을 드롭한다. 집 열쇠를 몰래 복사해서 제3자에게 넘기는 것과 같다. 이후 해당 시스템에 대한 지속적인 원격 접근이 가능해진다.
macOS, Linux, Windows 전부 대상이다. CI/CD 파이프라인에서 빌드가 돌아가는 환경이면 어디든 영향을 받는다. 로컬 개발 환경과 배포 서버 양쪽을 모두 점검해야 한다. Elastic Security Labs 분석에 따르면 C2 프로토콜은 HTTPS 위에 커스텀 커맨드 셋을 얹은 구조로, 평범한 API 트래픽과 구분하기 어렵게 설계됐다.
RAT이 설치되면 단순 환경변수 유출이 아니다. 시스템 전반 접근권을 공격자가 가진다.
process.env는 당연하고, 파일 시스템·네트워크 내부망·SSH 키·브라우저 저장 크리덴셜까지 이론상 전부 접근 가능하다. AWS_ACCESS_KEY, OPENAI_API_KEY, DATABASE_URL, NEXTAUTH_SECRET, STRIPE_SECRET_KEY — 이름이 무엇이든 빌드 타임에 주입된 값이면 전송 대상이다.
공격 벡터 — 유지 관리자 계정 탈취
SANS Institute와 The Hacker News 보도에 따르면 axios 유지 관리자 계정이 타깃형 사회공학 캠페인으로 탈취됐다. 공격자는 계정에 연결된 이메일을 ifstap@proton.me로 바꿨고, 이어 npm 발행 권한을 장악해 두 버전을 연달아 배포했다.
UNC1069/Sapphire Sleet은 과거에도 개발자를 겨냥한 공급망 공격 전력이 있다. 주요 접근 경로는 세 가지다. 첫째, 가짜 채용 제안 이메일 + 악성 코딩 테스트 파일. 둘째, LinkedIn·Telegram을 통한 가짜 헤드헌터 접촉. 셋째, 오픈소스 메인테이너 대상 피싱. axios 건은 세 번째 루트로 추정된다.
국가 지원 해킹 그룹이 배후라는 점에서 동기와 자원 수준이 다르다. 단순한 스크립트 키디가 아니다. 탐지 회피와 지속적인 접근 유지를 목표로 설계된 공격이다. 악성 패키지 하나로 전 세계 수십만 프로젝트에 동시 침투하는 전략이다.
지금 당장 확인하는 방법
두 줄이면 충분하다. 터미널에서 바로 실행한다.
npm list axios
# 악성 버전·패키지 포함 여부 확인 (lock 파일)
grep -E "axios@(1\.14\.1|0\.30\.4)|plain-crypto-js" package-lock.json
# 모노레포 전체 검색
find . -name "package-lock.json" -not -path "*/node_modules/*" | xargs grep -l "plain-crypto-js\|1.14.1\|0.30.4"
grep 결과가 나오면 즉시 조치가 필요하다. 아무것도 안 나오면 일단 안전하다. 단, git 히스토리도 확인해야 한다. 과거에 악성 버전이 설치됐다가 이후 정상 버전으로 업그레이드된 경우에도 postinstall 훅은 이미 실행된 뒤다.
git log -p -- package-lock.json | grep -E "1\.14\.1|0\.30\.4|plain-crypto-js"
pnpm을 쓴다면 pnpm list axios로 확인하고, yarn이면 yarn list --pattern axios로 조회한다. lock 파일 grep은 어떤 패키지 매니저든 동일하게 적용된다.
조치 방법
최신 안정 버전으로 업그레이드하고 lock 파일을 다시 생성한다.
rm -rf node_modules package-lock.json
# 2. 최신 안전 버전 설치
npm install axios@latest
# 3. 재확인
grep "plain-crypto-js" package-lock.json
# → 결과 없음이 정상
node_modules를 완전히 날리고 재설치하는 것이 가장 확실하다. 캐시가 남아있으면 소용없다. npm cache clean --force도 함께 실행해서 로컬 캐시까지 정리한다. 배포 환경(Vercel·Netlify·GitHub Actions 캐시 등)도 동일하게 적용해야 한다.
환경변수·크리덴셜 재발급
악성 버전이 설치된 적이 있다면 RAT이 시스템에 남아있을 가능성이 높다. 환경변수만이 아니라 시스템 전반의 크리덴셜을 전수 재발급해야 한다.
□ AWS / GCP / Azure 액세스 키
□ OpenAI / Anthropic / Gemini 등 AI API 키
□ 데이터베이스 비밀번호 (PostgreSQL, MySQL, MongoDB 등)
□ 결제 서비스 API 키 (Stripe, LemonSqueezy, Paddle 등)
□ GitHub Personal Access Token + SSH 키
□ NEXTAUTH_SECRET, SESSION_SECRET 등 앱 시크릿
□ 외부 서비스 웹훅 시크릿
□ 감염 의심 머신의 SSH 공개키 —
~/.ssh/authorized_keys 타 서버에서 제거
재발급 후에는 기존 키를 즉시 비활성화한다. 새 키로 교체하고 기존 키를 살려두면 의미가 없다. 서비스별로 키 교체 절차가 다르니 각 플랫폼 대시보드에서 직접 진행해야 한다.
감염 가능성이 높은 머신은 OS 재설치가 가장 안전하다. CI 러너 이미지는 clean rebuild, 로컬 개발 머신은 최소한 브라우저 세션·SSH 키·저장된 AWS CLI 프로파일 전부 삭제 후 재구성이 필요하다.
재발 방지 루틴
lock 파일을 반드시 git에 커밋한다. lock 파일은 설치된 정확한 버전을 고정시킨다. .gitignore에 빠져 있다면 지금 당장 추가한다. lock 파일이 없으면 빌드할 때마다 다른 버전이 설치될 수 있다.
npm audit을 CI 파이프라인에 포함시킨다. PR마다 자동으로 취약점을 검사하게 만든다. npm audit --audit-level=high로 고위험 취약점만 걸러도 기본적인 방어선은 생긴다. 단 npm audit은 CVE 공개 후에만 작동한다는 한계가 있다.
package.json의 버전 범위 지정자를 점검한다. ^1.13.0처럼 마이너 버전 자동 업데이트를 허용하면 악성 버전이 조용히 설치될 수 있다. 중요한 패키지는 정확한 버전(1.14.0)을 고정하거나 ~1.14.0(패치만 허용)으로 범위를 좁히는 것이 안전하다.
· Dependabot — GitHub 기본 제공. 취약점 발견 시 PR 자동 생성. 공개 CVE 기반
· Socket.dev — 공급망 공격 특화. 행동 분석으로 신규 공격도 탐지. 이번 axios 건도 초기 감지에 기여
· Snyk — 의존성 취약점 스캔 + 수정 제안. 무료 티어 있음
· Aikido Security — 이번 사건 최초 공개 분석 보고서 발행. 실시간 행동 분석 강점
· npm audit — 기본 내장. CVE 공개 데이터 기준이라 한계는 있음
Dependabot + Socket.dev 조합이 현실적이다. 단일 도구에 의존하면 사각지대가 생긴다.
왜 이런 일이 반복되나
npm 생태계는 패키지 발행 장벽이 낮다. 계정 하나만 탈취하면 수억 명이 쓰는 패키지를 오염시킬 수 있다. 이 구조는 단기간에 바뀌지 않는다.
XZ Utils(2024-03), event-stream(2018), ua-parser-js(2021), 그리고 이번 axios(2026-03) — 유명 패키지 공급망 공격 사례는 계속 나온다. axios가 처음도 아니고 마지막도 아니다. 오픈소스를 쓰는 이상 이런 위험은 구조적으로 사라지지 않는다.
npm은 이번 사건 후 2FA 의무화 확대와 메인테이너 이메일 변경 쿨다운(24시간) 도입을 검토 중이다. GitHub는 2024년부터 상위 npm 패키지 메인테이너에게 2FA를 강제했지만, 이번 탈취는 이메일 복구 흐름을 통한 우회였다. 보안 체인은 약한 고리만큼만 강하다.
정기적인 감사와 자동화된 모니터링이 현실적인 대응이다. 완벽한 방어는 없다. 빠른 탐지와 신속한 대응 루틴을 갖추는 것이 실질적이다. 이번 사건을 계기로 의존성 관리 루틴을 한 번 점검하는 게 맞다.
FAQ
Q. 언제 발생한 공격인가?
2026년 3월 31일 00:21 UTC에 axios@1.14.1, 01:00 UTC에 axios@0.30.4가 npm에 배포됐다. 악성 버전은 약 3시간 동안 레지스트리에 있었고 그 사이 추정 60만 건이 설치된 것으로 분석됐다.
Q. 안전한 버전은 뭔가?
악성 버전 이전의 정상 릴리스는 1.14.0과 0.30.3이다. axios 팀이 후속으로 발행한 클린 릴리스(1.15.0 이후, 0.30.5 이후)도 안전하다. npm install axios@latest로 업그레이드하면 된다.
Q. npm audit으로 다 잡을 수 있나?
발생 초기에는 불가능했다. npm audit은 공개된 CVE 데이터베이스 기준이다. 신규 공급망 공격처럼 아직 등록되지 않은 취약점은 통과된다. Socket.dev나 Aikido처럼 행동 분석 기반 도구를 보완으로 써야 한다.
Q. yarn이나 pnpm도 해당되나?
패키지 매니저와 무관하다. npm 레지스트리에서 같은 패키지를 가져오는 이상 동일하게 영향을 받는다. lock 파일 확인 명령만 달라진다. yarn은 yarn.lock, pnpm은 pnpm-lock.yaml에서 grep하면 된다.
Q. 누가 한 짓인가?
Microsoft Threat Intelligence는 북한 연계 Sapphire Sleet에, Google GTIG는 같은 그룹을 UNC1069로 추적한다. 두 회사가 공동 귀속을 확인했다. 금전 탈취가 주목적이고 암호화폐 관련 조직이 주요 타깃으로 알려져 있지만, 이번 공격은 범용 개발자를 대상으로 한 대규모 캠페인 성격이 강하다.
Q. 모노레포 환경에서는 어떻게 확인하나?
루트 node_modules뿐 아니라 각 워크스페이스 하위 package-lock.json도 확인해야 한다. find . -name "package-lock.json" -not -path "*/node_modules/*" | xargs grep "plain-crypto-js"로 전체를 한 번에 검색하는 것이 가장 빠르다.
이번 사건은 의존성 관리를 한 번쯤 다시 들여다볼 계기다. lock 파일 커밋, 정기 audit, 실시간 모니터링 — 세 가지만 지켜도 대부분의 공급망 공격은 일찍 잡힌다.
유명 패키지를 신뢰하는 것과 검증하는 것은 다른 일이다. axios를 쓴다면 오늘 버전 확인을 루틴에 넣어두는 것이 맞다.
· axios 공식 포스트모템 (GitHub #10636)
· Microsoft Security Blog — Mitigating the Axios npm supply chain compromise
· Google Cloud Threat Intelligence — UNC1069 분석
· Aikido Security — 최초 공개 분석
· Elastic Security Labs — RAT 기술 분석
· Socket.dev — plain-crypto-js 공개 분석
· Snyk 보안 블로그
이 글은 2026년 4월 기준 공개된 Microsoft·Google·Aikido·Elastic·Socket.dev·SANS·The Hacker News 분석 자료를 바탕으로 작성됐다. 이후 상황이 변경될 수 있으므로 공식 채널을 함께 확인하기 바란다.
보안 취약점 정보는 공개 시점에 따라 달라질 수 있다. 이 글의 내용을 그대로 사용할 경우 발생하는 결과에 GoCodeLab은 책임을 지지 않는다.