2026년 3월 30일, 누군가 인터넷에서 가장 많이 쓰이는 JavaScript 패키지 중 하나를 탈취했어요. 그리고 npm install 한 번으로 수만 대의 머신에 백도어를 설치했습니다.
그 패키지는 Axios. 주간 다운로드 1억 회. 지난 10년간 JavaScript로 뭔가를 만들어본 사람이라면 거의 확실히 써본 HTTP 라이브러리예요. 공격자는 Axios의 소스 코드를 단 한 줄도 바꾸지 않았어요. 대신 관리자 계정을 탈취하고, 몇 시간 전에 만든 가짜 패키지 하나를 의존성에 추가한 뒤 업데이트를 배포했어요. 그 가짜 패키지는 설치되는 순간 OS를 탐지하고, 맞춤형 원격 접근 트로이(RAT)를 다운로드해 실행한 뒤, 스스로를 삭제했어요. node_modules 폴더를 열어볼 때쯤이면 이미 사라진 뒤였습니다.
이게 뭔데?
소프트웨어 공급망 공격(Supply Chain Attack)이에요. 여러분이 직접 쓰는 코드가 아니라, 여러분의 코드가 의존하는 패키지를 공격하는 방식이죠.
이번 사건의 흐름을 풀어볼게요.
- 관리자 계정 탈취
공격자가 Axios npm 관리자의 계정을 탈취했어요. 오래 사용하던 npm 토큰이 유출된 것으로 추정돼요. - 가짜 패키지 사전 배치
공격 39분 전,plain-crypto-js@4.2.1이라는 악성 패키지를 npm에 등록했어요. 정상적인 crypto-js를 복제한 뒤 postinstall 스크립트에 악성코드를 삽입한 거예요. - Axios 업데이트 배포
탈취한 계정으로axios@1.14.1과axios@0.30.4를 배포하면서, 의존성 목록에 plain-crypto-js를 추가했어요. GitHub에는 태그도 릴리스도 없는 유령 업데이트였어요. - 자동 감염
^1.14.0범위로 Axios를 쓰는 프로젝트가npm install을 실행하면, 자동으로 1.14.1이 설치되고, plain-crypto-js의 postinstall 스크립트가 실행돼요. - 플랫폼별 RAT 배포
macOS면 Apple 시스템 데몬으로 위장한 바이너리를, Windows면 PowerShell을 wt.exe로 복사해 EDR을 우회하고, Linux면 Python 스크립트를 실행해요. - 증거 인멸
악성 스크립트(setup.js)를 삭제하고, postinstall 훅이 없는 깨끗한 package.json으로 교체해요. 사후 조사 시 node_modules를 열어봐도 정상 패키지처럼 보여요.
Google Threat Intelligence는 이 공격을 북한 연계 위협 행위자 UNC1069로 귀속시켰어요. 보안 업체 Huntress가 모니터링한 135개 엔드포인트에서, 악성코드는 설치 후 89초 만에 공격자 서버로 연결됐어요.
Axios만의 문제가 아니에요
같은 분기에 발생한 TeamPCP 캠페인은 더 심각했어요. 보안 스캐너 Trivy의 GitHub Actions 토큰을 탈취한 뒤, 자기 복제 웜(CanisterWorm)이 66개 이상의 npm 패키지로 전파됐어요. 8일 만에 GitHub Actions → Docker Hub → npm → PyPI → VS Code 마켓플레이스까지 5개 생태계를 오염시켰습니다.
뭐가 달라지는 건데?
공급망 공격 자체는 새로운 게 아니에요. SolarWinds(2020), Log4Shell(2021), XZ Utils(2024)까지 — 들어본 이야기죠. 그런데 지금은 두 가지가 동시에 바뀌었어요.
| 전통적 공급망 공격 | AI 에이전트 시대 공급망 공격 | |
|---|---|---|
| 공격 준비 기간 | 수개월~수년 (XZ Utils: 2년간 신뢰 구축) | 수시간~수일 (Axios: 39분 만에 완료) |
| 전파 범위 | 단일 패키지·단일 생태계 | 자동 전파, 5개 생태계 동시 감염 |
| 의존성 결정 주체 | 개발자가 직접 검토 | AI 에이전트가 자동 설치, 검토 시간 ≈ 0 |
| 탐지 방식 | CVE 데이터베이스 대조 (npm audit) | 행동 분석 필요 (CVE 없는 신규 악성코드) |
| 업계 평균 탐지 시간 | 267일 (SolarWinds: 14개월) | Socket: 6분 만에 탐지 (63,000배 빠름) |
| 감염 후 피해 시작 | 수일~수주 | 89초 (설치 → C2 서버 연결) |
a16z는 이 문제의 핵심을 이렇게 정리해요 — "공격 표면은 사람이 감시할 수 있는 속도보다 빠르게 확장되고, 의존성 결정을 내리는 주체는 점점 사람이 아니게 되고 있다."
AI 에이전트가 위험을 증폭시키는 3가지 경로
1. 취약한 버전을 더 자주 선택한다
11만 7천 건의 의존성 변경을 분석한 연구에 따르면, AI 에이전트는 사람보다 알려진 취약 버전을 50% 더 자주 선택해요. 게다가 그 취약 버전은 수정하려면 메이저 업그레이드가 필요한 경우가 훨씬 많아요.
2. 존재하지 않는 패키지를 추천한다 (슬롭스쿼팅)
LLM이 추천하는 패키지의 약 20%가 실제로 존재하지 않는 이름이에요. 공격자는 이걸 이용해요. AI가 반복적으로 추천하는 가짜 이름을 미리 등록하고 악성코드를 심어두는 거예요. 한 연구자가 이 방식으로 더미 패키지를 올렸더니 몇 주 만에 3만 건이 다운로드됐어요 — 대부분 AI 자동화 워크플로에서.
3. 자율 에이전트는 "작동하냐"만 본다
프로덕션에 투입된 자율 코딩 에이전트는 의존성 설치, 빌드 실행, PR 생성까지 사람 개입 없이 해요. 이들의 최적화 기준은 "작동하는가?"이지 "안전한가?"가 아니에요. 보안 검토 시간이 사실상 0으로 압축돼요.
핵심만 정리: 시작하는 법
AI 에이전트를 쓰든 직접 코딩하든, 공급망 보안은 이제 선택이 아니에요. 지금 당장 할 수 있는 방어법을 정리했어요.
- lockfile 기반 설치 강제
npm ci를 기본으로 사용하세요.npm install과 달리 lockfile에 명시된 정확한 버전만 설치해요. CI/CD 파이프라인에서npm install을 쓰고 있다면 즉시 교체하세요. - 행동 분석 기반 보안 도구 도입
CVE 대조만 하는npm audit를 넘어서, 패키지가 실제로 무엇을 하는지 분석하는 도구를 도입하세요. Socket(네트워크 접근, 셸 실행, 환경변수 읽기 감지)이나 Oligo(런타임 행동 감시) 같은 도구가 대표적이에요. - AI 에이전트 권한 제한
자율 코딩 에이전트가 의존성을 추가할 때 사람 승인을 거치게 하세요. Claude Code의--permission-prompt-tool이나 Cursor의 의존성 설치 확인 프롬프트 같은 기능을 활성화하세요. - 의존성 범위 최소화
^1.14.0같은 캐럿(^) 범위 대신, 정확한 버전(1.14.0)을 지정하거나 Renovate/Dependabot으로 관리형 업데이트를 하세요. 새 버전이 나와도 자동으로 설치되지 않아요. - postinstall 스크립트 차단
npm config set ignore-scripts true를 설정하면 패키지 설치 시 자동 실행 스크립트를 차단해요. Axios 사건의 악성코드는 postinstall 훅으로 실행됐어요. 필요한 스크립트만 화이트리스트로 허용하세요. - 정기적 의존성 감사
npx socket optimize같은 도구로 프로젝트의 전이적 의존성을 주기적으로 스캔하세요. 평균 JS 프로젝트의 755개 전이적 의존성 중 여러분 팀이 직접 선택한 건 극히 일부예요.
이미 감염됐을 수 있다면?
lockfile에서 axios@1.14.1, axios@0.30.4, plain-crypto-js@4.2.1을 검색하세요. 있다면 즉시 안전한 버전으로 롤백하고, macOS는 /Library/Caches/com.apple.act.mond, Windows는 %PROGRAMDATA%\wt.exe, Linux는 /tmp/ld.py 파일 존재 여부를 확인하세요.

