스캐너가 내는 것, 못 내는 것
한 줄 요약
Trivy·Grype 같은 스캐너는 이미지와 의존성을 취약점 데이터베이스와 대조해 "여기 걸린다" 는 목록을 냅니다. 하지만 그 목록은 무엇을 고칠지 는 말해 주지 않습니다 — 그 판단은 도달성과 범위를 사람이 붙여야 나옵니다.
왜 이게 필요했나
이미지 하나를 스캔하면 빨간 줄이 수십, 수백 개 나옵니다. 전부 심각도 순으로 고치려 하면 영영 끝나지 않고, 정작 급한 것이 그 더미에 묻힙니다. 스캐너를 켜는 일은 쉽습니다. 그 결과를 운영 가능한 작업 목록으로 바꾸는 일이 어렵고, 그게 이 코스의 주제입니다.
어떻게 동작하나
도구는 역할이 나뉩니다.
| 도구 | 하는 일 |
|---|---|
| syft | 이미지·파일 트리에서 SBOM(무엇이 들어 있나)을 만든다 |
| Trivy / Grype | SBOM 이나 이미지를 취약점 DB 와 대조해 CVE 목록을 낸다 |
Trivy 는 이미지를 두 묶음으로 봅니다 — OS 패키지(os-pkgs: 베이스 이미지의 apt/apk 패키지)와 애플리케이션 의존성(lang-pkgs: requirements.txt, package-lock.json 등). 둘은 고치는 방법이 다릅니다. OS 쪽은 대개 베이스 이미지를 올리면 한꺼번에 해결되고, 앱 쪽은 의존성 버전을 올려야 합니다.
실제로 돌리는 명령은 이렇습니다(연결된 환경에서).
syft payweb:1.4 -o cyclonedx-json > sbom.json
trivy image --format json --output scan.json payweb:1.4
trivy image --ignore-unfixed --severity HIGH,CRITICAL payweb:1.4
여기서 중요한 운영 사실 하나 — 스캐너는 취약점 DB 가 있어야 합니다. Trivy DB 는 약 136MB 이고 ghcr.io 에서 매일 갱신됩니다(자바 전용 DB 는 약 990MB). 그래서 폐쇄망에서는 이 DB 를 사내로 미러해 두고 --skip-db-update 로 돕니다. DB 가 오래되면 새 CVE 를 놓치고, 스캔 결과가 "깨끗하다" 고 거짓말을 합니다. CI 에 스캐너를 넣을 때 DB 갱신 전략을 함께 정하는 이유입니다.
스캐너가 못 내는 것
리포트에는 CVE·패키지·심각도·수정 버전이 있지만, 두 가지가 빠져 있습니다.
- 도달성: 그 취약 함수가 우리 코드에서 실제로 호출되는가. 스캐너는 "그 패키지가 설치돼 있다" 만 압니다. full_load 에 버그가 있어도 우리가 safe_load 만 쓴다면 그 CVE 는 우리에게 닿지 않습니다.
- 범위: 그 패키지가 배포 산출물에 실리는가, 아니면 빌드·테스트에만 쓰는가. 개발 전용 의존의 CVE 는 사용자에게 닿지 않습니다.
이 둘을 붙여야 "CRITICAL 42개" 가 "오늘 고칠 3개" 로 줄어듭니다.
English corner
- vulnerability scanner: 취약점 스캐너. 이미지·의존성을 CVE DB 와 대조합니다.
- SBOM (software bill of materials): 소프트웨어 자재 명세. 무엇이 들어 있는지의 목록입니다.
- fixed version / unfixed: 수정 버전 / 아직 수정이 없는 것.
- false sense of security: 근거 없는 안심. 오래된 DB 가 주는 "깨끗함" 이 그 예입니다.
다음 레슨에서 할 것
다음 모듈에서 Trivy 형식 리포트를 읽어 심각도·도달성·범위로 우선순위를 정하고, 베이스를 올려 다시 재고, 근거 있는 예외를 남기는 흐름을 손으로 해 봅니다.
한 걸음 더 — 어디서, 언제 스캔하나
스캔은 한 번이 아니라 여러 지점에서 돕니다. 개발자의 손(커밋 전), CI(빌드할 때), 레지스트리(이미지가 올라올 때), 그리고 운영 중(새 CVE 가 어제 공개됐을 수 있으므로 주기적으로)입니다. 같은 이미지라도 어제는 깨끗했는데 오늘 빨간 줄이 생깁니다 — 코드가 바뀐 게 아니라 DB 가 새 CVE 를 알게 됐기 때문입니다. 그래서 '빌드 때 통과했으니 영원히 안전' 은 틀린 생각이고, 배포된 이미지도 계속 다시 스캔해야 합니다.
스캐너를 CI 에 넣을 때 흔한 실수는 '어떤 것이든 발견되면 빌드 실패' 로 두는 것입니다. 그러면 fix 없는 취약점 하나 때문에 모든 빌드가 막히고, 팀은 곧 스캐너를 꺼 버립니다. 관문은 '고칠 수 있고 도달 가능하고 심각한 것' 으로 좁혀야 지속됩니다.
점검 순서
- SBOM(무엇이 들어 있나)과 스캔(무엇이 걸리나)을 구분하는가.
- OS 와 앱 취약점을 나눠 보는가(고치는 수단이 다르다).
- DB 갱신 전략이 있는가(폐쇄망이면 미러).
- 발견에 도달성·범위를 붙여 관문을 좁혔는가.