2026년 4~5월 사이 공급망 공격이 4건 연속으로 터졌다. Bitwarden CLI npm 패키지, KICS, SAP npm 패키지, Vercel OAuth 토큰 노출 — 사고 유형은 달라도 결론은 같다. 의존성 하나가 감염되면 그걸 쓰는 프로젝트 전체가 동시에 뚫린다. Sonatype State of the Software Supply Chain 2024 보고서에 따르면 오픈소스 공급망 공격은 2019년 대비 742% 증가했고, 악성 npm 패키지는 2024년 한 해만 70만 건 이상 탐지됐다.
2026년 4~5월 공급망 사고 4건
Bitwarden CLI npm 패키지 침해
공격자가 Bitwarden CLI npm 패키지 게시에 사용되는 자동화 토큰을 탈취해 악성 버전을 공식 레지스트리에 올렸다. GitHub Security Advisories에 보고된 이 사고의 핵심은 타깃이 Bitwarden CLI 자체가 아니라는 점이다. Bitwarden CLI는 CI/CD 파이프라인에서 시크릿 볼트를 꺼내는 도구로 광범위하게 쓰인다. npm publish 권한이 있는 토큰을 CI 환경 변수에 수명 제한 없이 넣어두고, 별도 보호 없이 장기 운영한 것이 직접 원인이었다.
KICS 공급망 사고 — 보안 도구도 예외는 없다
Checkmarx의 인프라 코드 보안 스캐너 KICS에서도 같은 시기 공급망 침해가 보고됐다. 보안 전문 기업 SENTRIX에서 레드팀 운영 중 확인한 패턴인데, 공격자들은 오히려 보안 도구를 경로로 선호한다 — 조직 내부 신뢰도가 높아 탐지가 느리기 때문이다.
SAP npm 패키지 악성 코드 — postinstall 스크립트가 무기가 되는 방식
SAP 생태계에서 사용되는 npm 패키지에서 악성 코드가 발견됐다. 악성 코드는 환경 변수와 로컬 파일 시스템을 스캔해 자격증명을 외부로 전송하는 방식으로 동작했다. npm install을 입력하는 순간, 코드 한 줄 보지 않고도 시스템이 이미 감염될 수 있다. OWASP Top 10 2021에서 A08로 분류된 소프트웨어 및 데이터 무결성 실패가 정확히 이 유형이다.
Vercel OAuth 토큰 노출 — scope 최소화 실패의 대가
Vercel의 GitHub OAuth 연동 과정에서 토큰이 노출되는 문제가 보고됐다. IBM Cost of a Data Breach 2024 보고서에 따르면 공급망 침해를 포함한 서드파티 소프트웨어 취약점으로 인한 평균 데이터 침해 비용은 4,610만 달러로, 전체 침해 유형 중 가장 높은 수준이다.
"The software supply chain is now the primary attack surface. Attackers don't need to compromise your code — they compromise your dependencies." — Sonatype State of the Software Supply Chain 2024
npm·CI/CD 점검 5단계
1단계 — npm audit 정기화
npm audit
npm audit --audit-level=high
단, npm audit은 알려진 CVE에만 반응한다. 악성 코드가 새로 심어진 경우 즉시 탐지가 안 된다. npm advisory 데이터베이스는 github.com/advisories에서 직접 조회할 수 있다.
2단계 — lockfile 커밋 강제 + drift 차단
npm ci
npm install 대신 npm ci를 쓰면 lockfile과 실제 설치 버전이 다를 때 에러로 멈춘다. CI에서는 무조건 npm ci다.
3단계 — npm provenance 확인
npm view <패키지명> --json | grep -i provenance
npm publish --provenance
npm v9.5.0부터 패키지 게시 시 provenance(출처 서명)를 붙일 수 있다. npm provenance 공식 문서에서 전체 설정 방법을 확인할 수 있다.
4단계 — SBOM 생성·관리
npx @cyclonedx/cyclonedx-npm --output-file sbom.json
SBOM(Software Bill of Materials)은 프로젝트에 들어간 모든 의존성의 명세서다. 새 취약점이 공개됐을 때 grep bitwarden sbom.json 한 줄로 영향 여부를 즉시 확인할 수 있다.
5단계 — CI 토큰 권한 분리
npm token list
npm token revoke <token-id>
더 안전한 방법은 GitHub OIDC를 npm 인증에 연결하는 것이다. 장기 토큰을 저장하지 않고, 워크플로가 실행될 때만 일회성 자격증명을 발급받는 방식이다.
자주 묻는 질문
npm audit만 정기적으로 돌리면 공급망 공격을 막을 수 있나요?
충분하지 않습니다. npm audit은 알려진 CVE를 기반으로 하기 때문에, 악성 코드가 새로 심어진 패키지는 CVE가 등록되기 전까지 탐지가 안 됩니다. lockfile 고정·provenance 검증·SBOM이 함께 돼야 현실적인 방어가 됩니다.
package-lock.json을 .gitignore에 넣으면 안 되는 이유가 뭔가요?
lockfile이 없으면 npm install을 실행할 때마다 최신 버전을 당겨옵니다. 어제 안전하던 패키지가 오늘 악성 버전으로 교체돼도 아무런 경고 없이 설치됩니다.
npm provenance는 어떤 패키지에 필요한가요?
직접 npm 레지스트리에 패키지를 게시하는 팀이라면 반드시 적용해야 합니다. 외부 패키지를 사용하는 입장에서는 npm view 명령으로 provenance가 붙어 있는지 확인하는 것이 좋습니다.
SBOM은 어떤 형식으로 만들어야 하나요?
CycloneDX와 SPDX가 현재 업계 표준입니다. npm 프로젝트라면 cyclonedx-npm 패키지로 바로 생성할 수 있습니다.
CI/CD 파이프라인에서 npm 토큰 관리를 어떻게 해야 하나요?
기존 토큰을 모두 목록화하고, 사용하지 않거나 만료 기한이 없는 토큰을 즉시 revoke합니다. 중장기적으로는 GitHub OIDC를 npm 인증에 연결해서 장기 토큰 자체를 없애는 것이 가장 안전합니다.
정리
AI 코딩으로 빠르게 만든 프로젝트일수록 의존성 검토가 빠지기 쉽다. 빌드된 프로젝트의 의존성 점검을 자동화하고 싶다면 codescan.kr 무료 진단을 시작점으로 쓸 수 있다.