Git 공급망 보안(Supply Chain Security): 코드 신뢰 체인 구축하기
커밋 위조·비밀 유출·의존성 혼란·악성 Action 등 Git 공급망 공격 유형과 대응책, GitHub Secret Scanning, GitHub Actions SHA 핀닝, SLSA/Sigstore 프로비넌스 서명, Dependabot 설정까지 실무 보안 레이어를 설명한다.
지난 글에서 PAT 관리를 다뤘다. 이번에는 더 넓은 시야로 Git 기반 소프트웨어 공급망 전체의 보안을 살펴본다. 의존성·CI·서드파티 Action이 모두 공격 경로가 될 수 있다.
소프트웨어 공급망이란
소프트웨어는 코드를 직접 작성하는 것 외에도 수많은 외부 요소를 사용한다. npm 패키지, GitHub Actions, Git 서브모듈, 빌드 도구, CI 환경이 모두 공급망(supply chain)이다. 공격자는 이 경로 중 하나를 장악해 최종 소프트웨어에 악성 코드를 심는다.
대표 사례: 2020년 SolarWinds 공격, 2021년 ua-parser-js npm 패키지 하이재킹, 2022년 PyTorch 의존성 혼란 공격.
주요 공격 유형과 대응
1. 커밋 위조 (Author Spoofing)
git config user.email은 누구든 임의로 설정할 수 있다. 서명이 없으면 커밋 작성자가 실제 그 사람인지 확인할 방법이 없다.
대응: GPG 또는 SSH 서명 + 브랜치 보호 규칙 Require signed commits 활성화. 서명 없는 커밋은 main에 push할 수 없도록 강제한다.
2. 비밀 정보 유출 (Secret Leak)
API 키, PAT, 데이터베이스 비밀번호가 커밋에 포함되면 공개 레포에서 즉시 노출된다. 히스토리에 남은 비밀은 삭제하기도 어렵다.
대응: git-secrets, gitleaks 등 pre-commit hook으로 push 전 차단. GitHub Secret Scanning으로 push 후 자동 감지 및 revoke.
# gitleaks pre-commit 설치
brew install gitleaks
gitleaks protect --staged # staged 파일 스캔
3. 의존성 혼란 (Dependency Confusion)
내부 레지스트리의 패키지와 같은 이름의 악성 패키지를 공개 npm/PyPI에 올리면, 패키지 매니저가 더 높은 버전으로 판단해 자동 설치할 수 있다.
대응: package-lock.json(npm), poetry.lock(Python), go.sum(Go) 등 lockfile을 반드시 커밋. 내부 패키지는 스코프(@company/pkg)를 사용하고 프라이빗 레지스트리를 .npmrc에 명시한다.
4. 악성 GitHub Actions
써드파티 Action이 태그로 참조될 경우, 태그가 다른 커밋으로 이동하면 악성 코드가 실행될 수 있다.
대응: SHA 핀닝. 태그 대신 불변인 커밋 SHA를 참조한다.
GitHub Actions SHA 핀닝
# 위험한 방식 (태그는 변경 가능)
- uses: actions/checkout@v4
# 안전한 방식 (SHA는 불변)
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
SHA가 변경되면 Dependabot이 자동으로 PR을 열어 준다.
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
GitHub Secret Scanning
공개·비공개 레포 모두에서 push 시 자동으로 알려진 비밀 패턴을 스캔한다. 감지되면 이메일 경고를 보내고 일부 파트너 서비스(GitHub, AWS 등)에는 자동 revoke도 가능하다.
Settings → Security → Secret scanning에서 활성화 여부를 확인한다. Push protection도 함께 활성화하면 비밀이 포함된 push를 서버에서 차단한다.
SLSA와 Sigstore
SLSA(Supply chain Levels for Software Artifacts)는 빌드 출처(provenance)를 증명하는 프레임워크다. “이 바이너리는 이 소스에서 이 빌드 환경으로 만들어졌다”를 서명해 검증한다.
Sigstore의 cosign으로 컨테이너 이미지·바이너리에 키리스(keyless) 서명을 적용할 수 있다.
# cosign으로 컨테이너 서명
cosign sign --key cosign.key ghcr.io/alice/myapp:latest
# 서명 검증
cosign verify --key cosign.pub ghcr.io/alice/myapp:latest
SBOM 생성
SBOM(Software Bill of Materials)은 소프트웨어에 포함된 모든 구성 요소 목록이다. GitHub는 레포 내 의존성을 자동으로 분석해 SBOM을 JSON으로 내려받는 기능을 제공한다.
# GitHub CLI로 SBOM 내려받기
gh api repos/alice/repo/dependency-graph/sbom | jq '.'
실무 체크리스트
- main 브랜치에 Require signed commits 활성화
- Secret Scanning + Push protection 활성화
- GitHub Actions를 SHA로 핀닝하고 Dependabot으로 자동 업데이트
- 모든 lockfile 커밋 (package-lock.json, poetry.lock, go.sum)
.env·비밀 파일은.gitignore에 추가, CI Secrets로 주입- PAT는 Fine-grained + 최소 스코프 + 만료일 설정
지난 글: Token vs Password: GitHub 인증 방식 변천사
다음 글: Git Hooks 개요: 자동화의 시작점
읽어주셔서 감사합니다. 😊