요약
2024년, NPM 공급망 공격으로 3,000개 이상의 악성 패키지가 급증했고, 2026년 3월 Axios 침해는 상위 10개 패키지조차 안전하지 않다는 점을 보여주었습니다. 이 가이드는 API 개발자가 반드시 적용해야 할 방어 계층을 다룹니다: 록파일 적용, postinstall 스크립트 차단, 출처 확인, 행동 분석 도구 활용, 그리고 공격 표면을 줄이는 아키텍처 선택법까지 실전 중심으로 설명합니다.
서론
2026년 3월 31일 발생한 Axios 공급망 공격은 npm 침해의 대표적 사례로, 단일 탈취 계정에서 배포된 크로스 플랫폼 RAT가 주간 8,300만 다운로드의 패키지에 삽입되었습니다. npm의 전형적인 방어(종속성 업데이트, 록파일, 버전 고정 등)를 모두 우회한 이 공격은, 도구 체인의 단일 패키지만 손상되어도 API 키, DB 자격 증명, 클라우드 토큰이 유출될 수 있음을 증명했습니다.
💡 Apidog는 API 테스트용 내장 HTTP 클라이언트를 제공하여, 테스트 스택에서 Axios, node-fetch, got 등 npm 종속성을 제거할 수 있습니다. 아래의 방어 전략을 적용하면서 npm 종속성 표면을 줄이려면 Apidog를 무료로 다운로드해 보세요.
이 가이드는 기본 록파일 위생부터 고급 행동 분석까지, 실전에서 바로 적용 가능한 7가지 계층적 방어법을 설명합니다.
계층 1: 록파일 적용
록파일이 중요한 이유
록파일은 모든 패키지와 전이적 종속성의 정확한 버전을 기록합니다. 록파일 없이 npm install을 실행하면 semver 범위에 맞는 최신(악성) 버전이 설치될 수 있습니다. 예를 들어 package.json이 "axios": "^1.14.0"일 때, 악성 1.14.1이 등록되어 있으면 그것이 설치됩니다.
실전 규칙
항상 록파일을 커밋:
package-lock.json,yarn.lock,pnpm-lock.yaml,bun.lock등 록파일을 반드시 버전 관리에 포함하세요.CI/CD에서는 고정 설치만 사용:
자동화 환경에서는 아래 명령어를 사용하세요.
# npm
npm ci
# yarn
yarn install --frozen-lockfile
# pnpm
pnpm install --frozen-lockfile
# bun
bun install --frozen-lockfile
- 풀 리퀘스트에서 록파일 변경점 리뷰: PR에서 록파일이 바뀌면, 새로운 종속성, 버전, 레지스트리 URL 등이 추가됐는지 꼭 확인하세요. Socket.dev와 같은 도구를 활용하면 자동 감지가 가능합니다.
록파일의 한계
첫 설치(초기화)나 신규 종속성 추가 시에는 악성 버전이 고정될 수 있습니다. 즉, 록파일은 계층 1일 뿐 완전한 보호가 아닙니다.
계층 2: postinstall 스크립트 비활성화
공격 벡터: postinstall
Axios, ua-parser-js, event-stream 등 대형 npm 공격들은 모두 postinstall 스크립트를 활용했습니다. 이 훅은 패키지 설치 중, 코드 리뷰/보안 도구 개입 이전에 실행됩니다.
스크립트 전역 차단
.npmrc에 아래 설정을 추가하세요.
ignore-scripts=true
또는 CLI로:
npm config set ignore-scripts true
이렇게 하면 모든 라이프사이클 스크립트(preinstall, install, postinstall, prepare) 실행이 차단됩니다.
스크립트가 필요한 패키지 예외 처리
- 옵션 1: 설치 후 필요한 패키지만 재빌드
npm ci --ignore-scripts
npm rebuild bcrypt sharp
-
옵션 2: 허용 목록 사용 (npm 10+)
.scriptsrc.json파일 생성:
{
"allowScripts": {
"bcrypt": true,
"sharp": true
}
}
- 옵션 3: 미리 빌드된 바이너리 활용 많은 패키지가 이제 미리 빌드된 바이너리를 제공하므로, postinstall이 필요 없는지 확인하세요.
PackageGate 주의사항
2026년 1월 공개된 "PackageGate" 취약점에 따르면, Git 기반 종속성은 ignore-scripts로도 코드 실행이 가능합니다. Git 종속성은 반드시 특정 커밋 해시로 고정하고, 저장소 내용을 직접 감사해야 합니다.
계층 3: 정확한 버전 고정
semver 범위 대신 고정 버전
npm 기본은 캐럿(^)을 붙여 설치합니다:
{
"axios": "^1.14.0"
}
이 대신, 정확한 버전을 사용하도록 .npmrc에 아래를 추가하세요:
save-exact=true
save-prefix=''
직접:
{
"axios": "1.14.0"
}
전이적 종속성 재정의
- npm:
{
"overrides": {
"axios": "1.14.0",
"plain-crypto-js": "npm:empty-npm-package@1.0.0"
}
}
- yarn:
{
"resolutions": {
"axios": "1.14.0"
}
}
- pnpm:
{
"pnpm": {
"overrides": {
"axios": "1.14.0"
}
}
}
트레이드오프
정확한 버전 고정은 자동 패치 적용이 어렵다는 단점이 있습니다. 보안 우선 프로젝트에는 반드시 수동으로 패치 일정을 관리하세요.
계층 4: 패키지 출처(provenance) 확인
출처란?
npm의 출처 증명은 Sigstore 서명으로, 패키지가 어떤 소스 저장소·커밋·CI/CD 환경에서 빌드됐는지 암호화 증명을 제공합니다.
출처 확인 방법
npm audit signatures
자동화된 출처 확인이 표준이었다면, 많은 제로데이 공격이 즉시 차단될 수 있습니다.
직접 패키지 배포 시 출처 활성화
- GitHub Actions 예시:
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- run: npm publish --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
-
.npmrc에 추가:
provenance=true
제한 사항
출처는 선택 사항이며, 현재 대부분의 패키지는 지원하지 않습니다. 또한, 출처는 "어디서 빌드됐는가"만 증명하고 소스 코드 안전성까지 보장하지는 않습니다.
계층 5: 행동 분석 도구 활용
취약점 스캔을 넘어서
npm audit이나 Snyk는 알려진 CVE만 탐지합니다. 제로데이 멀웨어는 놓칩니다.
Socket.dev
Socket.dev는 설치/런타임 중 패키지의 실제 동작을 분석하여, 네트워크 요청, 외부 파일 접근, 환경 변수 수집, 난독화된 코드 등 이상 동작을 감지합니다.
- CLI 설치 및 스캔:
npm install -g @socketsecurity/cli
socket scan
Snyk
Snyk는 취약점 위험도, 수정 가이드까지 제공합니다(행동 분석은 불가).
npm install -g snyk
snyk test
계층적 통합
두 도구와 npm audit을 모두 CI/CD에 추가하세요.
npm audit
socket scan
snyk test
각각의 경고가 빌드를 차단하도록 설정합니다.
계층 6: 종속성 표면 최소화
종속성 트리 감사
node_modules의 모든 패키지가 신뢰 대상입니다. 종속성 수를 줄이면 공격 면도 줄어듭니다.
# 종속성 개수 확인
npm ls --all | wc -l
# 중복/다중 종속성 확인
npm ls --all | sort | uniq -c | sort -rn | head -20
점검 질문
- Node.js에 내장된 기능이 아닌가?
- 전이적 종속성 수가 많은가?
- 소규모 유틸리티라면 벤더링(코드 직접 포함)할 수 있는가?
네이티브 대안 예시
| 패키지 | 네이티브 대안 | 사용 가능 버전 |
|---|---|---|
| axios, node-fetch, got |
fetch (글로벌) |
Node.js 18+ |
| uuid | crypto.randomUUID() |
Node.js 19+ |
| dotenv |
--env-file 플래그 |
Node.js 20.6+ |
| chalk | util.styleText() |
Node.js 21.7+ |
| glob | fs.glob() |
Node.js 22+ |
| path-to-regexp | URL Pattern API | Node.js 23+ |
API 테스트의 경우
API 테스트 워크플로우는 HTTP 클라이언트, 어설션, 테스트 러너, 모의 서버 등 여러 npm 패키지에 의존합니다.
Apidog은 이 모든 스택을 통합합니다:
- HTTP 클라이언트: 내장형, npm 종속성 불필요
- 어설션/테스트 빌더: 시각적/내장 지원
- 테스트 러너: Apidog CLI로 CI/CD 연동
- 모의 서버: 동적 응답, 별도 Express 등 불필요
- 문서화: 사양 자동 생성
API 테스트를 Apidog로 옮기면 테스트 인프라에서 수십 개 npm 종속성이 사라집니다.
계층 7: 네트워크 및 런타임 모니터링
악성 도메인 차단
공급망 공격 이후에는 네트워크 레벨에서 악성 인프라를 즉시 차단하세요.
# /etc/hosts에 악성 도메인 추가
echo "0.0.0.0 sfrclak.com" | sudo tee -a /etc/hosts
CI/CD 환경에서는 npm 레지스트리, Git 호스트 등 필수 도메인만 허용하세요.
StepSecurity Harden-Runner 활용
GitHub Actions에서 실시간 네트워크/프로세스/파일 모니터링을 제공합니다.
- uses: step-security/harden-runner@v2
with:
egress-policy: audit # 엄격 모드: block
런타임 프로세스 모니터링
개발 머신에서는 osascript, cscript, python3 등 의심스러운 자식 프로세스 실행을 EDR(엔드포인트 탐지/대응) 도구로 감지하세요.
권장 .npmrc 구성
아래는 위 모든 계층을 반영한 보안 .npmrc 예시입니다:
# 정확한 버전 고정
save-exact=true
save-prefix=
# 라이프사이클 스크립트 비활성화
ignore-scripts=true
# 게시를 위한 출처 활성화
provenance=true
# 공식 레지스트리 사용
registry=https://registry.npmjs.org/
# 게시를 위한 2FA 요구
auth-type=web
# 감사 레벨 임계값
audit-level=moderate
이 파일을 저장소에 커밋하여 팀 전체에 적용하세요.
CI/CD 보안 파이프라인 예시
아래는 7가지 계층을 모두 적용하는 GitHub Actions 워크플로우입니다:
name: Secure Build
on: [push, pull_request]
jobs:
security-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: step-security/harden-runner@v2
with:
egress-policy: audit
- uses: actions/setup-node@v4
with:
node-version: 22
# 계층 1+2: 고정 록파일, 스크립트 없음
- run: npm ci --ignore-scripts
# 계층 3: 예상치 못한 버전 없음 확인
- run: npm ls --all > deps.txt
# 계층 4: 출처 확인
- run: npm audit signatures
# 계층 5: 행동 분석
- run: npx socket scan
# 계층 5: 취약점 스캔
- run: npx snyk test
# 계층 1: 기본 감사
- run: npm audit --audit-level=moderate
# 허용된 네이티브 종속성만 다시 빌드
- run: npm rebuild sharp bcrypt
npm 보안의 다음 단계
인기 패키지 출처 의무화
npm은 다운로드 임계값 이상의 패키지에 출처 증명(provenance) 의무화를 논의 중입니다.
2인 릴리스 승인
고위험 패키지 릴리스 시 2인 관리자가 승인하도록 하는 제도가 검토 중입니다.
런타임 권한 범위 지정
Deno와 같은 런타임 권한 모델을 Node.js에도 도입하면, postinstall 스크립트의 무분별한 네트워크/파일 접근을 제한할 수 있습니다.
패키지 관리자 컨버전스
pnpm의 엄격 격리 모델(선언된 종속성만 접근 가능)이 npm에도 도입되면, 공급망 공격의 표면이 더욱 줄어듭니다.
FAQ
npm에서 공급망 공격이란?
애플리케이션이 아닌, 종속성 체인을 노리는 공격입니다. 계정 탈취, 악성 코드 삽입, 타이포스쿼팅 등으로 사용자가 종속성 설치/업데이트 시 악성 코드가 실행될 수 있습니다.
npm audit만으로 충분한가요?
아닙니다. npm audit은 알려진 취약점만 탐지하며, 제로데이(예: Axios 침해)는 잡지 못합니다. Socket.dev 같은 행동 분석 도구를 함께 사용하세요.
npm 사용을 중단해야 하나요?
아닙니다. npm은 가장 큰 생태계이며, 대부분 안전합니다. 정확한 버전 고정, 록파일 적용, 스크립트 차단, 종속성 최소화로 노출을 줄이세요.
Apidog는 공급망 위험을 어떻게 줄이나요?
Apidog는 API 개발에 필요한 HTTP 클라이언트, 테스트 러너, 모의 서버, 문서 생성기를 내장하여 npm 종속성을 대폭 줄입니다.
npm에서 패키지 출처란 무엇인가요?
Sigstore로 소스 저장소 및 CI/CD 빌드 환경과 암호화 방식으로 연결하는 증명입니다. npm audit signatures로 확인할 수 있습니다.
악성 npm 패키지는 얼마나 많은가요?
2024년 기준, Snyk는 3,000개 이상을 탐지했고, Sonatype은 분기당 12만 건의 멀웨어 공격을 차단했습니다. 대부분 타이포스쿼팅이지만, 대형 패키지 침해도 발생합니다.
PackageGate 취약점이란?
2026년 1월, Git 기반 종속성이 라이프사이클 스크립트 비활성화 상태에서도 코드 실행이 가능한 제로데이 취약점 6종이 발표되었습니다. Git 종속성은 반드시 커밋 해시로 고정하세요.
핵심 요약
- 록파일 적용은 기본이지만, 공격 기간 첫 설치에는 무력화됨
-
.npmrc에ignore-scripts=true로 postinstall 스크립트 전역 비활성화 -
save-exact=true로 semver 범위로 인한 자동 업데이트 차단 -
npm audit signatures로 패키지 출처 확인 - Snyk(취약점), Socket.dev(행동 분석),
npm audit(기본) 모두 계층적으로 활용 - Node.js 네이티브 API 및 Apidog와 같은 통합 플랫폼 사용으로 종속성 최소화
- StepSecurity Harden-Runner로 CI/CD 네트워크 모니터링
모든 종속성은 신뢰 결정의 대상입니다. 종속성이 적을수록 공격 표면이 줄어듭니다. 계층적 방어를 적용하면 침투 난이도는 크게 상승합니다. 고립된 조치가 아닌, 심층적이고 실질적인 방어를 실천하세요.



Top comments (0)