SecuritySupply ChainSBOMCI/CD SecurityDevSecOpsDependency
소프트웨어 공급망 공격 이해와 방어 — SBOM부터 CI/CD 보안까지
2026년 4배 증가한 공급망 공격의 주요 벡터와 SBOM, 의존성 검증, CI/CD 파이프라인 보안 강화 방법을 설명합니다.
VWV2026-03-155분 읽기
공급망 공격이란?
공급망 공격은 신뢰받는 소프트웨어 공급 경로를 악용하여 최종 사용자를 감염시키는 공격입니다. 직접 공격 대신 개발 도구, 오픈소스 패키지, 빌드 파이프라인에 침투하여 배포 단계에서 악성코드를 주입합니다. Sonatype의 2025 State of the Software Supply Chain 보고서에 따르면 오픈소스 생태계를 노린 공급망 공격은 2020년 이후 매년 급증 추세입니다.
[공격자]
↓ 오픈소스 패키지 오염
[npm / PyPI 저장소]
↓ 개발자가 의존성 설치
[개발 환경]
↓ CI/CD 파이프라인을 통해 배포
[프로덕션 서버]
↓ 수천~수만 명의 사용자에게 전파
주요 공격 벡터
1. 타이포스쿼팅 (Typosquatting)
# 정상 패키지
npm install lodash
# 타이포스쿼팅 악성 패키지 (오타 유도)
npm install 1odash # 소문자 L → 숫자 1
npm install lodahs # 철자 오류
npm install lodash-utils # 기능 패키지인 척
2. 의존성 혼동 (Dependency Confusion)
내부 패키지: @company/auth-utils (버전 1.0.0)
공격자: npm에 @company/auth-utils 공개 패키지 게시 (버전 9.9.9)
결과: npm이 더 높은 버전의 공개 패키지를 우선 설치
3. 유지관리자 계정 탈취
이메일 피싱 또는 비밀번호 재사용으로 인기 패키지의 npm/PyPI 계정을 탈취한 후 악성 버전을 게시합니다.
방어 전략 1 — SBOM(소프트웨어 자재 명세서)
SBOM은 소프트웨어에 포함된 모든 컴포넌트 목록으로, 취약 컴포넌트를 즉시 파악하는 데 사용됩니다.
Syft로 SBOM 생성
# 설치
brew install syft # macOS
# 또는
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh
# 프로젝트 SBOM 생성
syft dir:./my-app -o spdx-json > sbom-spdx.json
syft dir:./my-app -o cyclonedx-json > sbom-cyclonedx.json
# Docker 이미지 SBOM
syft myapp:latest -o cyclonedx-json > container-sbom.json
Grype로 취약점 스캔
# 설치
brew install grype
# SBOM 기반 스캔
grype sbom:./sbom-cyclonedx.json
# 직접 스캔
grype dir:./my-app
# CI에서 Critical 취약점 발견 시 빌드 실패
grype dir:./my-app --fail-on critical
출력 예시
| 패키지 | 버전 | 취약점 | 심각도 | 수정 버전 |
|---|---|---|---|---|
| lodash | 4.17.20 | CVE-2021-23337 | High | 4.17.21 |
| axios | 0.21.0 | CVE-2021-3749 | Medium | 0.21.2 |
| log4j | 2.14.1 | CVE-2021-44228 | Critical | 2.17.1 |
방어 전략 2 — 의존성 고정
// package.json — 정확한 버전 고정
{
"dependencies": {
"express": "4.18.2", // O: 정확한 버전
"lodash": "~4.17.21", // 주의: 패치 버전만 허용
"axios": "^1.6.0" // 위험: 마이너 버전까지 자동 업데이트
}
}
# package-lock.json / yarn.lock 무결성 검증
npm ci # install 대신 ci 사용 (lockfile 엄격 준수)
# 패키지 서명 검증 (npm 9+)
npm audit signatures
방어 전략 3 — CI/CD 파이프라인 보안
GitHub Actions 보안 강화
# .github/workflows/secure-build.yml
name: Secure Build
on: [push, pull_request]
permissions:
contents: read # 최소 권한만 부여
security-events: write # SARIF 업로드용
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false # 자격증명 캐싱 비활성화
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
- name: SBOM 생성
uses: anchore/sbom-action@v0
with:
artifact-name: sbom.spdx.json
- name: 취약점 스캔
uses: anchore/scan-action@v3
with:
fail-build: true
severity-cutoff: critical
시크릿 관리
# 위험: 소스 코드에 하드코딩
API_KEY = "sk-1234abcd..." # 절대 금지!
# 안전: 환경 변수 + Secrets Manager 사용
import os
import boto3
def get_secret(secret_name: str) -> str:
client = boto3.client("secretsmanager", region_name="ap-northeast-2")
response = client.get_secret_value(SecretId=secret_name)
return response["SecretString"]
API_KEY = os.environ.get("API_KEY") or get_secret("prod/api-key")
방어 전략 4 — 프라이빗 패키지 레지스트리
[내부 개발자]
↓ pip install / npm install
[내부 Nexus/Artifactory]
↓ 화이트리스트 검증 후 프록시
[공개 PyPI / npm]
# pip — 내부 레지스트리만 허용
pip install --index-url https://pypi.company.internal/simple/ \
--no-index \
requests
# npm — .npmrc 설정
registry=https://registry.company.internal
//registry.company.internal/:_authToken=${NPM_TOKEN}
공급망 보안 성숙도 모델
| 단계 | 활동 | 도구 |
|---|---|---|
| 기초 | 의존성 목록 파악 | npm audit, pip-audit |
| 중급 | SBOM 자동 생성 | Syft, SPDX |
| 고급 | 서명 검증, 아티팩트 서명 | Sigstore, Cosign |
| 최고 | SLSA 레벨 3 달성 | SLSA 프레임워크 |
정리
공급망 공격은 방어가 어렵지만, SBOM 생성·관리, 의존성 고정, CI/CD 파이프라인 하드닝, 시크릿 안전 관리를 통해 리스크를 크게 줄일 수 있습니다. DevSecOps 문화를 정착시켜 보안을 개발 초기 단계부터 통합하세요.