
오픈소스 취약점 관리의 시작, OSV Scanner 완전 정복
오픈소스 의존성이 폭발적으로 늘어나면서 “우리 서비스가 어떤 취약한 라이브러리를 쓰고 있는지”를 정확히 파악하는 것이 점점 더 중요해지고 있습니다. OSV Scanner는 Google이 개발한 오픈소스 취약점 스캐너로, 다양한 언어·패키지 생태계를 한 번에 검사할 수 있는 도구입니다.
OSV Scanner 개념 → 설치와 기본 사용 → CI/CD·SIEM·자산관리 연동 → 우선순위 산정 → 자동화·운영 팁
OSV Scanner란 무엇인가?
1. OSV(Open Source Vulnerabilities) 데이터베이스
OSV Scanner는 OSV.dev 취약점 데이터베이스를 기반으로 동작합니다.
- 각 오픈소스 패키지의 버전 범위 단위로 취약점을 관리
- CVE, GHSA 등 여러 소스를 통합
- Python, Node.js, Go, Rust, Java, Ruby 등 다양한 언어 지원
- “지금 우리 프로젝트에서 사용하는 정확한 버전이 취약한지”를 중심으로 검사
즉, 단순히 “CVE 목록을 검색”하는 것이 아니라,
실제 프로젝트의 의존성(버전 포함)을 분석해 해당 버전이 취약한지 여부를 판별해 줍니다.
2. 지원하는 주요 생태계
대표적으로 아래 환경들을 지원합니다.
- Node.js: npm, Yarn (
package-lock.json,yarn.lock,pnpm-lock.yaml등) - Python:
requirements.txt,Pipfile.lock, Poetry - Go:
go.mod,go.sum - Java/Maven, Gradle
- Rust: Cargo
- 기타: SBOM(CycloneDX, SPDX 등) 파일 기반 스캔
설치 및 기본 사용법
1. 설치 방법
두 가지 방식이 많이 쓰입니다.
Go로 설치
go install github.com/google/osv-scanner/cmd/osv-scanner@latest
$GOPATH/bin 이 PATH에 포함되어 있어야 osv-scanner 명령을 바로 사용할 수 있습니다.
바이너리 다운로드
curl -L https://github.com/google/osv-scanner/releases/latest/download/osv-scanner_linux_amd64 -o osv-scanner
chmod +x osv-scanner
sudo mv osv-scanner /usr/local/bin/osv-scanner
다른 OS(Windows, macOS)도 릴리즈 페이지에서 다운로드해서 비슷하게 사용하면 됩니다.
2. 기본 스캔 패턴
1) Lockfile 기반 스캔
가장 권장되는 방식입니다. 실제로 설치된 의존성 버전을 정확히 알 수 있기 때문입니다.
# Node.js
osv-scanner --lockfile=package-lock.json
osv-scanner --lockfile=yarn.lock
# Python
osv-scanner --lockfile=requirements.txt
osv-scanner --lockfile=Pipfile.lock
여러 개의 lockfile을 동시에 지정할 수도 있습니다.
osv-scanner \
--lockfile=requirements.txt \
--lockfile=package-lock.json
2) 디렉터리 재귀 스캔
프로젝트 전체에 대해 “알아서 lockfile을 찾아 스캔”하는 방식입니다.
osv-scanner -r /path/to/project
# 또는 현재 디렉터리
osv-scanner -r .
3) SBOM 파일 스캔
이미 SBOM(CycloneDX, SPDX 등) 파일을 생성해두었다면 이를 그대로 사용할 수 있습니다.
osv-scanner --sbom=sbom.json
이를 통해 Docker 이미지/컨테이너, 빌드 아티팩트 등 다양한 형태의 자산을 스캔할 수 있습니다.
3. 출력 형식 (자동화 vs 사람이 읽기)
JSON 형식 (자동화에 최적)
osv-scanner -r . --format json --output vulnerabilities.json
- 내부 시스템, SIEM, 대시보드, 리포트 생성 스크립트 등에 연동하기 좋습니다.
테이블 형식 (사람이 바로 읽기)
osv-scanner -r . --format table
- CLI에서 바로 결과를 보거나, 개발자가 로컬에서 확인할 때 좋습니다.
SARIF 형식 (GitHub Security 탭 연동)
osv-scanner -r . --format sarif --output results.sarif
- GitHub의 Code Scanning Alerts와 연동할 수 있습니다.
CI/CD 파이프라인 통합 예시
1. GitHub Actions 예시
name: OSV Scanner
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run OSV Scanner
uses: google/osv-scanner-action@v1
with:
scan-args: |-
--recursive
--format json
--output osv-results.json
./
운영 포인트
pull_request이벤트에 연결하여 머지 전에 취약점 검사를 강제--format json+--output으로 결과를 파일로 남기고,
이후 단계에서 Slack 알림·이슈 자동 생성 등 추가 처리 가능- 특정 심각도 이상이면
exit 1로 빌드를 실패시키는 정책을 추가할 수 있음
조직 보안 인프라 통합 시나리오
이제부터는 OSV Scanner를 실제 보안 인프라와 어떻게 엮을 수 있는지에 집중해 봅니다.
1. SIEM(Wazuh 등) 연동 예시
아래 예시는 OSV Scanner 결과를 JSON 로그로 변환해서 Wazuh(또는 다른 SIEM)에 수집하는 예입니다.
#!/bin/bash
# osv-scan-wazuh.sh
PROJECT_PATH="/opt/applications"
WAZUH_LOG="/var/ossec/logs/osv-scanner.json"
# OSV 스캔 실행
osv-scanner -r "$PROJECT_PATH" --format json > /tmp/osv-results.json
# Wazuh 로그 형식으로 변환 (여기서는 예시 형태)
jq -c '.results[] as $r |
$r.vulnerabilities[]? as $v |
{
timestamp: (now | strftime("%Y-%m-%dT%H:%M:%S")),
scanner: "osv",
project: $r.source.path,
vuln_id: $v.id,
summary: $v.summary,
severity: $v.database_specific.severity
}' /tmp/osv-results.json >> "$WAZUH_LOG"
/var/ossec/bin/agent_control -r -a # 필요 시 에이전트 로그 전송 트리거
보안 체크포인트
- OSV 로그 파일 권한(읽기/쓰기)을 최소화했는가?
- SIEM에서
scanner="osv"필터로 대시보드를 만들었는가? - 특정 심각도 이상(CRITICAL/HIGH)은 별도 알림 룰로 분리했는가?
2. 취약점 우선순위 산정(EPSS, KEV, CVSS 연계)
취약점이 수십·수백 개 나오면, “뭘 먼저 고칠지”가 더 중요해집니다.
아래 예시는 OSV Scanner 결과에 대해 CVSS + EPSS + KEV 정보를 붙여 우선순위를 점수화하는 Python 스크립트 예시입니다.
실제 EPSS/KEV API는 각자 사용하는 데이터 소스에 맞게 구현해야 합니다. 여기서는 구조와 로직 예시 중심입니다.
#!/usr/bin/env python3
# osv_priority_mapper.py
import json
def get_epss_score(cve_id: str) -> float | None:
# TODO: 실제 EPSS API 연동
return None
def check_kev(cve_id: str) -> bool:
# TODO: CISA KEV 등 실제 데이터 연동
return False
def extract_cvss(vuln: dict) -> float | None:
scores = vuln.get("database_specific", {}).get("cvss", [])
if isinstance(scores, list) and scores:
return scores[0].get("score")
return None
def calculate_priority(cvss, epss, is_kev):
score = 0
if is_kev:
score += 100 # KEV 등록 시 최우선
if cvss:
score += cvss * 5
if epss:
score += epss * 30
return score
def enrich_osv_results(osv_results_file: str):
with open(osv_results_file) as f:
osv_data = json.load(f)
enriched = []
for result in osv_data.get("results", []):
project = result.get("source", {}).get("path", "unknown")
for vuln in result.get("vulnerabilities", []):
cve_id = vuln.get("id")
cvss_score = extract_cvss(vuln)
epss_score = get_epss_score(cve_id)
is_kev = check_kev(cve_id)
enriched.append({
"cve_id": cve_id,
"project": project,
"cvss": cvss_score,
"epss": epss_score,
"kev": is_kev,
"priority": calculate_priority(cvss_score, epss_score, is_kev),
"summary": vuln.get("summary", "")
})
enriched.sort(key=lambda x: x["priority"], reverse=True)
return enriched
if __name__ == "__main__":
results = enrich_osv_results("osv-results.json")
with open("prioritized-vulnerabilities.json", "w") as f:
json.dump(results, f, indent=2, ensure_ascii=False)
보안 운영 가이드
- KEV 등록 여부 + EPSS 상위 취약점을 최우선 패치 대상 그룹으로 지정
- 조직 내부 취약점 관리 프로세스(티켓, 변경관리, 배포 계획)와 연결
- “심각도 높은데 활용 가능성이 낮은 취약점” vs “심각도 중간인데 공격 가능성 높은 취약점” 간 밸런스를 고려
3. 자산 관리(Snipe-IT 등)와 연동
OSV Scanner 결과를 자산 관리 시스템에 태그/메모 형태로 연동하면, 자산 단위의 취약점 리스크를 한눈에 파악하기 좋습니다.
#!/bin/bash
# osv-snipeit-sync.sh
osv-scanner -r /opt/apps --format json > /tmp/osv-scan.json
python3 << 'EOF'
import json
import requests
SNIPEIT_URL = "https://snipeit.example.com"
SNIPEIT_TOKEN = "YOUR_API_TOKEN"
with open('/tmp/osv-scan.json') as f:
scan_data = json.load(f)
headers = {
"Authorization": f"Bearer {SNIPEIT_TOKEN}",
"Content-Type": "application/json",
}
for result in scan_data.get("results", []):
asset_path = result["source"]["path"]
vuln_count = len(result.get("vulnerabilities", []))
# 1) asset_path ↔ 자산 매핑 로직 설계 (예: 프로젝트명 → 자산 태그)
# 2) Snipe-IT API로 자산 검색 후
# 3) 커스텀 필드/노트에 vuln_count 또는 요약정보 업데이트
# 예시 (구체 API는 Snipe-IT 문서 참고)
# requests.post(f"{SNIPEIT_URL}/api/v1/hardware/{asset_id}", headers=headers, json={...})
EOF
체크포인트
- “리포지토리/서비스명 ↔ 자산ID” 매핑 테이블을 유지하고 있는가?
- 자산 목록에서 “취약점 개수, 마지막 스캔 날짜”를 한눈에 볼 수 있는가?
4. 정기 스캔 자동화 (Cron 기반)
운영 환경에서는 주기적인 스캔 + 알림 + 리포트가 필요합니다.
# crontab 예시 (root 또는 전용 계정)
# 매일 새벽 2시에 전체 프로젝트 스캔
0 2 * * * /opt/scripts/osv-daily-scan.sh
#!/bin/bash
# /opt/scripts/osv-daily-scan.sh
SCAN_TARGETS=(
"/opt/app/backend"
"/opt/app/frontend"
"/opt/app/api-gateway"
)
TODAY=$(date +%Y%m%d)
REPORT_DIR="/var/reports/osv/$TODAY"
mkdir -p "$REPORT_DIR"
for target in "${SCAN_TARGETS[@]}"; do
app_name=$(basename "$target")
osv-scanner -r "$target" \
--format json \
--output "$REPORT_DIR/${app_name}-vulnerabilities.json"
# CRITICAL 취약점 개수 계산
critical_count=$(jq '[.results[].vulnerabilities[]?
| select(.database_specific.severity == "CRITICAL")] | length' \
"$REPORT_DIR/${app_name}-vulnerabilities.json")
if [ "$critical_count" -gt 0 ]; then
# Slack 또는 이메일 알림 함수
send_alert "Critical vulnerabilities found in $app_name: $critical_count"
fi
done
# 월요일(1)에는 주간 리포트 생성
if [ "$(date +%u)" -eq 1 ]; then
python3 /opt/scripts/generate-weekly-report.py "$REPORT_DIR"
fi
운영 체크포인트
- 스캔 로그와 리포트 보관 기간(예: 6개월/1년)을 명시했는가?
- 스캔 실패(명령 오류, 권한 문제 등)를 감지하는 모니터링을 붙였는가?
- 개발/운영팀에 “언제 어떤 기준으로 스캔되는지” 가이드를 공유했는가?
고급 활용 팁
1. False Positive·예외 관리
어떤 취약점은 구조적으로 해당 기능을 사용하지 않아서 실제 영향이 없기도 합니다.
이때는 명시적인 예외 설정 + 만료일(expiry) 을 두고 관리하는 것이 중요합니다.
osv-scanner -r . --config osv-scanner.toml
# osv-scanner.toml
[[IgnoredVulns]]
id = "CVE-2023-XXXXX"
reason = "해당 기능(XX 모듈)을 사용하지 않아 실제 공격 경로 없음"
expiry = "2025-12-31"
보안 가이드
- 예외 등록 시 반드시 이유(reason) 와 검토 만료일(expiry) 를 남길 것
- 만료일 도래 시 재검토 프로세스(정기 리뷰)를 운영할 것
- 예외는 “임시 우회 조치”라는 인식을 명확히 할 것
2. Docker 이미지 스캔
트렌드는 이미지 → SBOM → 취약점 스캔 흐름입니다.
# 1. SBOM 추출 (예: Syft)
syft docker:my-image:latest -o cyclonedx-json > sbom.json
# 2. SBOM 기반 OSV 스캔
osv-scanner --sbom sbom.json
이 구조로 가면
- 레지스트리에서 이미지 다운로드 없이 SBOM만으로도 검토 가능
- CI/CD뿐 아니라 레지스트리 측면(이미지 등록 시)에서도 검사할 수 있음
3. Git 커밋 히스토리 스캔
과거 버전까지 포함해 “언제 어떤 취약 라이브러리가 사용됐는지”를 조사하고 싶을 때 사용할 수 있는 기능입니다.
osv-scanner --experimental-all-commits .
- 주로 보안 감사, 침해사고 후 회고 분석 시 유용합니다.
- 장기간 운영된 레포에서는 시간이 오래 걸릴 수 있으니, 범위를 브랜치/폴더 수준으로 제한하는 것도 방법입니다.
API Gateway(Kong 등) 기반 중앙 취약점 스캔 서비스
조직 내 여러 팀이 직접 OSV Scanner를 설치·사용하는 대신,
API 형태로 “lockfile 업로드 → 스캔 결과 반환” 서비스를 제공하는 구조도 만들 수 있습니다.
1. FastAPI 기반 예시
from fastapi import FastAPI, UploadFile, HTTPException
import subprocess
import json
import uuid
import os
app = FastAPI()
UPLOAD_DIR = "/tmp/osv-lockfiles"
os.makedirs(UPLOAD_DIR, exist_ok=True)
@app.post("/api/v1/scan/lockfile")
async def scan_lockfile(file: UploadFile):
"""lockfile 업로드 → OSV 스캔 → JSON 결과 반환"""
if not file.filename:
raise HTTPException(status_code=400, detail="filename is required")
tmp_name = f"{uuid.uuid4()}_{file.filename}"
tmp_path = os.path.join(UPLOAD_DIR, tmp_name)
with open(tmp_path, "wb") as f:
f.write(await file.read())
try:
result = subprocess.run(
["osv-scanner", "--lockfile", tmp_path, "--format", "json"],
capture_output=True,
text=True,
check=False,
)
finally:
os.remove(tmp_path)
if result.returncode not in (0, 1): # 0=정상, 1=취약점 존재
raise HTTPException(status_code=500, detail=result.stderr)
return json.loads(result.stdout)
@app.get("/api/v1/scan/repository")
async def scan_repository(repo_url: str):
"""
Git 저장소 URL → 클론 후 스캔 (구현 예시)
실제 운영에서는:
- 임시 디렉터리 생성
- git clone
- osv-scanner -r
- 결과 반환 후 디렉터리 삭제
"""
return {"message": f"Repository scan for {repo_url} is not implemented yet."}
이 API를 Kong, NGINX, 다른 API Gateway 뒤에 두고
- 사내 CI/CD, 개발자 툴, 포털에서 간단히 HTTP 호출만으로 OSV 스캔 사용
- 인증/인가, 요청 로깅, 레이트 리밋은 Gateway에서 통합 관리
내부 사용자(개발·운영팀)를 위한 보안 가이드 & 점검 포인트
1. 개발팀 가이드
- PR 생성 시 OSV Scanner가 자동으로 실행된다는 것을 인지시키기
- 취약점 발생 시 처리 기준 공유
- 예: CRITICAL/HIGH → 반드시 수정 후 머지
- MEDIUM → 우선순위 협의 후 일정 내 수정
- False Positive 또는 실제 영향이 없는 경우
- 보안팀과 협의 후
osv-scanner.toml에 예외 등록 - 이유와 만료일을 반드시 명시
- 보안팀과 협의 후
2. 보안팀/운영팀 체크포인트
- CI/CD 파이프라인마다 OSV Scanner가 어디에, 어떤 옵션으로 붙어 있는지 문서화
- 정기 스캔(Cron/batch) 결과가 SIEM·Slack·메일로 잘 전달되는지 주기적으로 점검
- 취약점 우선순위(KEV, EPSS, CVSS)를 반영한 패치 플랜 템플릿을 마련
- 자산 관리 시스템(예: Snipe-IT)에 “취약점 개수/마지막 스캔일” 메타데이터 추가
- 침해사고 분석 시 “그 시점 해당 서비스의 OSV 결과”를 함께 참고하는 문화 정착
마무리
OSV Scanner는 단순한 “취약점 스캐너”를 넘어,
CI/CD, SIEM, 자산관리, 우선순위 산정 시스템과 결합할 때 진짜 힘을 발휘하는 도구입니다.
- 개발자는 PR 단계에서 바로 취약 라이브러리를 인지하고 수정
- 보안팀은 EPSS·KEV·CVSS 기반으로 “어디부터 손대야 할지”를 명확히 판단
- 운영팀은 정기 스캔·리포트·알림을 통해 전체 리스크를 관리
위 예시들을 기반으로 각 조직 환경에 맞게 스크립트와 파이프라인을 커스터마이징하시면,
오픈소스 취약점 관리의 수준을 한 단계 끌어올릴 수 있을 것입니다.
댓글