SCA 스캔
프로젝트에서 사용하는 npm 패키지나 Docker 베이스 이미지에 보안 취약점이 있다면 어떻게 하시겠어요? SCA(Software Composition Analysis)는 컨테이너 이미지와 소프트웨어 의존성에 알려진 취약점(CVE)이 있는지 자동으로 분석해주는 기능입니다.
현대 소프트웨어는 수많은 외부 라이브러리에 의존합니다. 평균적으로 애플리케이션 코드의 80% 이상이 오픈소스 라이브러리로 구성됩니다. 이 라이브러리들 중 하나라도 보안 취약점이 있다면 전체 애플리케이션이 위험해질 수 있습니다. SCA는 이러한 숨겨진 위험을 자동으로 찾아줍니다.

개요
- 분석 대상: 컨테이너 이미지, 의존성 패키지
- 분석 시점: Build 단계 (빌드 후)
- 분석 엔진: Trivy
- 취약점 DB: NVD, Alpine SecDB, Red Hat Security Data 등 다양한 소스
분석 대상
SCA는 다양한 유형의 패키지와 이미지를 분석합니다.
이미지 취약점
Docker 이미지에 포함된 모든 패키지를 분석합니다.
- OS 패키지: Alpine, Debian, Ubuntu 등의 시스템 패키지 (apt, apk로 설치된 패키지)
- 언어 패키지: npm, pip, maven, go 등 언어별 패키지 매니저로 설치된 패키지
- 베이스 이미지: Dockerfile의 FROM 절에 지정된 베이스 이미지 자체의 취약점
의존성 취약점
프로젝트의 의존성 파일을 분석합니다.
package-lock.json(Node.js)requirements.txt,Pipfile.lock(Python)pom.xml,build.gradle(Java)go.sum(Go)Gemfile.lock(Ruby)composer.lock(PHP)
package.json만으로는 실제 설치된 버전을 정확히 알 수 없습니다. package-lock.json 같은 lock 파일에는 실제 설치된 정확한 버전이 기록되어 있어, 취약점이 있는 버전을 정확하게 탐지할 수 있습니다.
Step 1: SCA 스캔 시작하기
- [서비스 관리] 페이지로 이동합니다.
- 분석할 서비스를 선택합니다.
- 파이프라인에서 Build 단계를 클릭합니다.
- SCA 탭을 선택합니다.
- 스캔 시작 버튼을 클릭합니다.
Step 2: 스캔 대상 설정
2.1 이미지 선택
분석할 컨테이너 이미지를 선택합니다:
- 최신 빌드 이미지: 가장 최근에 빌드된 이미지를 자동으로 선택합니다 (권장)
- 특정 태그: 특정 버전의 이미지 태그를 지정합니다.
- 이미지 URL: 전체 이미지 경로를 직접 입력합니다 (예:
harbor.company.com/project/app:v1.2.3)
2.2 스캔 옵션
-
VEX Hub 필터링 (기본 활성화): 실제 영향이 없는 것으로 알려진 취약점(오탐)을 자동으로 필터링합니다. 노이즈를 줄이고 진짜 중요한 취약점에 집중할 수 있습니다.
-
심각도 필터 (기본 Medium): 설정한 심각도 이상의 취약점만 표시합니다. Low까지 모두 보면 너무 많을 수 있으니, 처음에는 Medium 이상으로 시작하세요.
-
무시 목록: 이미 확인하여 무시하기로 결정한 특정 CVE를 제외합니다.
Step 3: 스캔 실행
3.1 스캔 진행
스캔이 시작되면 다음과 같은 단계로 진행됩니다:
[1/4] Pulling image... ← 이미지 다운로드
[2/4] Scanning OS packages... ← OS 패키지 분석
→ Found 150 packages ← 150개 패키지 발견
→ Checking vulnerabilities... ← 취약점 확인 중
[3/4] Scanning application packages... ← 애플리케이션 패키지 분석
→ Found 85 npm packages ← 85개 npm 패키지 발견
→ Checking vulnerabilities... ← 취약점 확인 중
[4/4] Applying VEX filters... ← VEX 필터 적용
Scan completed! ← 완료
3.2 예상 스캔 시간
이미지 크기에 따라 스캔 시간이 달라집니다:
- 100MB 이하: 약 30초
- 100-500MB: 1-2분
- 500MB 이상: 2-5분
Step 4: 결과 확인
4.1 결과 요약
스캔이 완료되면 다음 정보를 한눈에 확인할 수 있습니다:
- 총 취약점: 탐지된 취약점의 총 개수
- 심각도 분포: Critical/High/Medium/Low별 취약점 수
- 수정 가능: 패키지 업데이트로 수정할 수 있는 취약점 수
4.2 취약점 상세
각 취약점을 클릭하면 다음 정보를 확인할 수 있습니다:
- CVE ID: 취약점의 고유 식별자 (예: CVE-2021-44228)
- 패키지명: 취약점이 있는 패키지 이름
- 현재 버전: 현재 설치된 버전
- 수정 버전: 취약점이 수정된 버전 (있는 경우)
- 심각도: CVSS 점수 기반 심각도
- 설명: 취약점에 대한 상세 설명
- 참조 링크: NVD, 공급사 보안 권고 등의 추가 정보
"수정 버전"이 표시된 취약점은 패키지를 업데이트하면 해결됩니다. 수정 버전이 없는 취약점보다 먼저 처리하면 빠르게 취약점 수를 줄일 수 있습니다.
취약점 유형
SCA가 탐지하는 대표적인 취약점 유형을 알아두면 위험도를 빠르게 파악할 수 있습니다.
OS 패키지 취약점
시스템 레벨의 취약점으로, 심각한 경우가 많습니다.
-
권한 상승: 일반 사용자가 root 권한을 획득할 수 있는 취약점
- 예) CVE-2021-3156 (sudo 취약점) - 로컬 사용자가 root 권한 획득 가능
-
원격 코드 실행: 외부에서 악성 코드를 실행할 수 있는 취약점
- 예) CVE-2021-44228 (Log4Shell) - Java 애플리케이션에서 원격 코드 실행 가능
-
서비스 거부(DoS): 서비스를 중단시킬 수 있는 취약점
- 예) CVE-2022-0778 (OpenSSL) - 무한 루프로 서비스 중단
언어 패키지 취약점
각 프로그래밍 언어 생태계에서 발견되는 취약점입니다.
- Node.js: Prototype Pollution(프로토타입 오염), XSS, ReDoS(정규식 서비스 거부)
- Python: Command Injection, Path Traversal, Deserialization 취약점
- Java: Deserialization, SSRF(Server-Side Request Forgery), XXE(XML External Entity)
VEX Hub 필터링
VEX란?
VEX(Vulnerability Exploitability eXchange)는 특정 취약점이 실제로 해당 제품에 영향을 미치는지를 평가한 데이터입니다. 예를 들어, 취약한 함수가 코드에 존재하더라도 실제로 그 함수가 호출되지 않으면 영향이 없습니다.
왜 필요한가요?
CVE 데이터베이스에 등록된 모든 취약점이 실제로 위험한 것은 아닙니다. VEX 필터링을 통해:
- 오탐 제거: 실제 영향이 없는 취약점을 제외
- 노이즈 감소: 수백 개의 취약점 중 진짜 중요한 것에 집중
- 정확한 우선순위: 실제 위험 기준으로 정렬
필터링 상태
각 취약점에는 다음과 같은 상태가 표시됩니다:
- Affected: 실제로 영향받음 - 조치가 필요합니다.
- Not Affected: 영향받지 않음 - VEX 필터에 의해 제외됩니다.
- Fixed: 이미 수정됨 - 최신 버전에서는 해결되었습니다.
- Under Investigation: 조사 중 - 아직 영향도가 확인되지 않았습니다.
VEX Hub 필터링을 활성화하면 실제 영향이 없는 취약점이 자동으로 제외되어, 진짜 중요한 취약점에 집중할 수 있습니다. 특별한 이유가 없다면 항상 활성화해두는 것을 권장합니다.
자동 스캔 설정
빌드 후 자동 스캔
빌드가 완료될 때마다 자동으로 SCA 스캔을 실행하도록 설정할 수 있습니다.
- Auto CI 설정에서 SCA를 활성화합니다.
- 빌드 완료 후 자동으로 SCA 스캔이 실행됩니다.
- 결과는 Build 단계에서 확인할 수 있습니다.
차단 정책
취약점 발견 시 배포를 자동으로 차단하는 정책을 설정할 수 있습니다.
- Critical 차단: Critical 심각도 취약점이 발견되면 배포 차단 (프로덕션 권장)
- High 차단: High 이상 심각도 취약점 발견 시 차단 (스테이징 권장)
- 알림만: 취약점 발견 시 알림만 보내고 배포는 진행 (개발 환경)
알려진 Critical 취약점이 있는 이미지가 프로덕션에 배포되면 심각한 보안 사고로 이어질 수 있습니다. 프로덕션 환경에서는 반드시 Critical 차단 정책을 활성화하세요.
취약점 수정
패키지 업데이트
가장 일반적인 수정 방법은 취약점이 해결된 버전으로 패키지를 업데이트하는 것입니다.
- 스캔 결과에서 "수정 버전"을 확인합니다.
- 해당 버전으로 의존성 파일을 업데이트합니다.
# Node.js 예시
npm update lodash
# Python 예시
pip install --upgrade requests - 이미지를 다시 빌드합니다.
- 재스캔하여 취약점이 해결되었는지 확인합니다.
베이스 이미지 변경
베이스 이미지 자체에 취약점이 많다면 더 최신 버전이나 다른 이미지로 변경하는 것이 효과적입니다.
# 취약한 버전 (오래된 Alpine)
FROM node:16-alpine3.14
# 수정된 버전 (최신 Alpine)
FROM node:20-alpine3.19
Alpine Linux는 최소한의 패키지만 포함하고 있어, Debian이나 Ubuntu 기반 이미지보다 취약점이 적은 경우가 많습니다. 가능하다면 Alpine 기반 이미지를 사용하는 것을 권장합니다.
문제 해결
스캔 실패
-
이미지 풀 실패: 컨테이너 레지스트리 인증 정보를 확인하세요. 토큰이 만료되었거나 권한이 부족할 수 있습니다.
-
타임아웃: 이미지 크기가 너무 큰 경우 타임아웃이 발생할 수 있습니다. 이미지 최적화를 고려하거나, 타임아웃 설정을 늘려보세요.
-
DB 업데이트 실패: 취약점 데이터베이스 업데이트에 실패한 경우입니다. 네트워크 연결을 확인하고 다시 시도해보세요.
과다 탐지 (너무 많은 취약점)
취약점이 너무 많이 탐지되어 관리가 어렵다면:
-
VEX 필터 활성화: 실제 영향이 없는 오탐을 자동으로 필터링합니다.
-
무시 목록 활용: 이미 확인하여 무시하기로 결정한 CVE를 목록에 추가합니다.
-
심각도 필터 조정: 처음에는 High 이상만 표시하고, 점차 범위를 넓혀가세요
-
베이스 이미지 교체: 취약점이 많은 베이스 이미지를 더 안전한 이미지로 교체하세요