취약점
Vulnerabilities 탭은 스캔 파이프라인이 프로젝트 컴포넌트와 상관시킨 모든 미해결 CVE(Common Vulnerabilities and Exposures)를 나열합니다. 결과는 스캔을 거쳐 영속화됩니다 — CVE가 한번 발견되면 근본 컴포넌트가 제거·업그레이드될 때까지 상태와 분류 노트와 함께 프로젝트 이력에 남습니다.

개별 결과를 분류하는 엔지니어; SLA를 추적하는 보안 리드. VEX 상태 변경은 developer 이상; 일괄 억제는 team_admin.
"Vulnerability data unavailable" 배너
Vulnerabilities 탭 상단에 파란색 Vulnerability data unavailable 배너가 나타나는 경우는, 포털이 스캔에서 발견한 컴포넌트 는 보여줄 수 있지만 finding 이 0 건일 때 — 보통 로컬 Trivy DB의 다운로드가 아직 끝나지 않았거나(워커가 막 부팅한 신규 배포), DB 다운로드가 실패한 경우입니다. 배너는 원인을 설명하고 다음 절차를 안내합니다.
- 관리자는 워커 디스크의 Trivy DB를 확인해야 합니다 — 정확한 명령은 취약점 데이터 — 동작 확인 참조. 곧 도착할
/admin/health하위의 Vulnerability data 카드(roadmap)가 UI에서 신선도를 노출합니다. - Trivy DB가 자리 잡으면 자동 재매칭 beat이 모든 프로젝트의 최신 SBOM에서 finding을 가져옵니다 — 사용자 측 인앱 액션은 필요 없습니다. 배너는 적어도 한 건의 finding이 반환되는 다음 페이지 로드에서 자동으로 사라집니다.
배너는 정보성 이지 에러가 아닙니다 — 실제로 깨끗한 프로젝트의 0 findings 는 API 레벨에서 동일하게 보이므로, 메시지는 의도적으로 단정하지 않고 진단 표면을 가리킵니다.
심각도 모델
| 심각도 | 색상 토큰 | CVSS v3 (일반) | 빌드 게이트 |
|---|---|---|---|
| Critical | #dc2626 | 9.0–10.0 | 종료 코드 1(기본) |
| High | #ea580c | 7.0–8.9 | 프로젝트별 설정 |
| Medium | #ca8a04 | 4.0–6.9 | 영향 없음 |
| Low | #2563eb | 0.1–3.9 | 영향 없음 |
| Info | #71717a | — | 영향 없음 |
기본 정책은 Critical에서만 빌드를 실패시킵니다. 프로젝트 소유자는 임계치를 High로 낮출 수 있습니다.
VEX 상태 머신
결과는 CycloneDX VEX(Vulnerability Exploitability eXchange) 7-state 모델을 따릅니다. 각 결과는 신규에서 시작하며 분석가가 분류함에 따라 전환됩니다.
| 상태 | 정의 | 빌드 게이트 |
|---|---|---|
| 신규 (New) | 막 발견됨; 분류되지 않음. | 카운트. |
| 분석 중 (Analyzing) | 분류 진행 중. | 카운트. |
| 악용 가능 (Exploitable) | 이 프로젝트 맥락에서 악용 가능 확인. | 카운트. |
| 해당 없음 (Not affected) | 컴포넌트는 있으나 취약 코드 경로에 도달 불가. | 제외. |
| 오 탐 (False positive) | 탐지 자체가 잘못됨(예: 잘못된 purl). | 제외. |
| 억제됨 (Suppressed) | 운영자가 명시적으로 침묵 처리(not_affected + 명시적 억제). | 제외. |
| 수정됨 (Fixed) | 해결됨(컴포넌트 업그레이드 또는 패치 적용). | 제외. |
전환은 행위자, previous_status, new_status, 필수 사유 메시지와 함께 감사 로그에 기록됩니다.
필수 사유
New / Analyzing 외 상태로 전환할 때마다 자유 텍스트 사유(10자 이상)가 필요합니다. 포털은 사유를 그대로 저장합니다 — 사실 기반으로 작성하세요("lodash를 4.17.21로 업그레이드", "취약 코드 경로는 dev_only 모듈에 있음"). 본 텍스트는 CycloneDX VEX 출력에 그대로 노출됩니다.
결과 테이블
컬럼:
- CVE — CVE-YYYY-NNNN 식별자 (평문 표시; NVD 클릭 이동은 로드맵 항목).
- 심각도 (Severity) — 색상 배지.
- CVSS — 상위 피드의 CVSS v3 숫자 점수.
- EPSS — EPSS 확률을 백분율로 표시(예:
97.3%). EPSS 값이 없는 CVE는—로 표시됩니다. EPSS — 악용 확률 참고. - KEV — CVE가 CISA KEV(Known Exploited Vulnerabilities, 알려진 악용 취약점) 카탈로그에 등재된 경우 표시되는 배지와 카탈로그의 대응 기한. KEV — 알려진 악용 취약점 참고.
- 제목 (Title) — 권고문의 짧은 요약.
- 영향 (Affected) — 영향 받는 컴포넌트(
name@version). - 상태 (Status) — 현재 VEX 상태.
- SLA 기한 (SLA due) — 조치 SLA 기한을 기한 초과 / 임박 / 여유 세 상태로 구분해 표시합니다. SLA가 없는 심각도는
—로 표시됩니다. 조치 SLA와 경과시간 추적 참고. - 발견 시각 (Discovered) — 이번 스캔이 결과를 기록한 시점. 재스캔하면 초기화됩니다. SLA 시계는 이 값이 아니라 최초 탐지 시각을 씁니다 — 최초 탐지 vs. 발견 시각 참고.
상단 인라인 필터 바: 심각도, 상태, EPSS 임계 필터(min_epss), SLA 상태 필터(sla), 그리고 검색 박스(CVE ID / 제목 / 컴포넌트 자유 텍스트), 정렬·정렬 순서 컨트롤. 기본 정렬은 Priority — KEV 등재 결과가 먼저, 다음은 심각도, 그다음은 EPSS 순입니다. Priority 정렬 참고. 정렬 컨트롤에는 EPSS(sort=epss)와 SLA 기한(sort=sla_due)도 포함되며, 해당 값이 없는 행은 마지막으로 정렬됩니다.
툴바에는 그룹화 컨트롤도 있어 플랫 결과 테이 블을 업그레이드 중심의 조치 작업 목록으로 바꿔 볼 수 있습니다 — 업그레이드별 보기 참고.
드로어 — 결과 상세
행을 클릭하면 다음을 봅니다.
- 요약 (Summary) — 제목, 설명, CWE, CVSS 벡터, 그리고 Trivy DB가 제공할 때의 EPSS score와 percentile(미제공 시
—). EPSS — 악용 확률 참고. CVE가 CISA KEV 카탈로그에 등재되어 있으면 KEV 배지와 대응 기한도 여기에 표시됩니다 — KEV — 알려진 악용 취약점 참고. 요약에는 SLA 칩(기한과 기한 초과 / 임박 / 여유 상태)과 SLA 시계의 시작점인 최초 탐지 행도 표시됩니다 — 조치 SLA와 경과시간 추적 참고. - 참고 자료 (References) — 벤더 권고, 수정 커밋, 익스플로잇 데이터베이스.
- 영향 (Affected) — 상위에서 보고한 영향 범위와 본 프로젝트 컴포넌트 버전 강조, 그리고 수정 버전(fixed version) — 이 컴포넌트에 대해 이 CVE를 해소하는 버전 — 을 스캔 파이프라인이 판별할 수 있었던 경우 표시합니다. 수정 버전 — CVE를 해소하는 버전 참고. 영향 컴포넌트는 의존성 깊이()도 함께 표시합니다: 직접 선언한 직접(direct) 의존성(깊이
1)인지, 다른 패키지가 끌어온 전이(transitive) 의존성(깊이2+)인지. 직접 의존성의 CVE 는 대개 선언 버전을 올려 본인이 고치고, 전이 의존성의 CVE 는 그것을 요구하는 직접 부모를 업그레이드해 고칩니다 — 직접 vs. 전이 (의존성 깊이) 참고. - 분석 (Analysis) — VEX 상태 전환별 액션 버튼, 현재 상태에서 허용된 전환마다 한 개씩 표시됩니다. 모든 종결 결정은
analyzing상태를 거치므로 새로 발견된 finding 은 곧바로 verdict 로 넘어갈 수 없습니다. 버튼을 클릭하면 사유 입력 다이얼로그가 열리며 제출합니다.developer이상만 가능하며,Suppressed로의 전이는team_admin이상이 필요합니다. - 이력 (History) — VEX 상태 전환 타임라인(누가, 언제, 어떤 사유로 상태를 변경했는지).

일괄 상태 전이
여러 finding 이 같은 디스포지션을 공유할 때 — 예를 들어 방금 업그레이드한 동일 라이브러리의 10 개 finding — 툴바의 Bulk action bar 로 드로어를 일일이 열지 않고 한 번에 전이할 수 있습니다.

- 행 단위 체크박스(또는 헤더 트라이-스테이트 체크박스로 현재 페이지의 모든 행 선택 — 필터·페이지가 변경되면 선택이 자동으로 클리어되어 stale 선택이 뷰를 건너 leak 되지 않음) 를 체크합니다.
- 표 상단의 액션 바가 선택 개수와, 선택된 행들의 공통 현재 상태에서 가능한 verdict 들을 보여줍니다. 선택이 상태를 섞어 합법적 다음 상태의 교집합이 비면 verdict 버튼이 비활성화되고 툴팁이 이유를 설명합니다.
- verdict 를 선택하고 justification 을 한 번만 입력(같은 텍스트가 모든 행에 적용)한 뒤 submit.
응답은 행 단위 입니다 — 선택된 모든 finding 이 결과 alert 에 결과를 받습니다. 각 행은 success·HTTP 형식의 status_code·기계 판독 error 코드를 담습니다. 코드는 다음과 같습니다.
- transitioned —
success: true,status_code: 200,error: null. 상태가 실제로 변경됨. - already_at_target —
success: true,status_code: 200,error: "already_at_target". 행이 이미 요청한 상태였음; 멱등 no-op 은 실패가 아니라 성공입니다(audit 행만 남기지 않음). - invalid_transition —
success: false,status_code: 422. 워크플로 매트릭스가 허용하지 않는 전이; 행에allowed_to(다음 허용 상태)가 실립니다. - forbidden —
success: false,status_code: 403. 행위자의 역할이 부족함(예:developer가 행을Suppressed로). - not_found —
success: false,status_code: 404. id 가 이 프로젝트의 finding 이 아님.
envelope 의 succeeded / failed 개수는 이를 합산합니다(already_at_target 은 succeeded 로 집계). alert 가 닫히면 표가 새 상태를 반영하며 reload 됩니다.
서버 쪽에서 요청은 선택된 finding id 목록·target status·justification 을 담은 단일 POST /v1/projects/{id}/vulnerabilities:bulk-transition 호출입니다. 엔드포인트는 행 단위 엔드포인트와 동일한 상태 머신 가드를 적용하며, 실제 전이된 finding 당 audit-log 행 1 개를 emit 합니다. 한 호출 당 상한은 200 ids 입니다 — 그보다 큰 선택은 페이지를 넘기며 청크 단위로 submit 하세요.
team_admin 권한 필요bulk 엔드포인트는 행 단위 엔드포인트의 권한을 확장하지 않습니다. 선택된 어느 행이라도 Suppressed 로 옮기려면 여전히 프로젝트 팀의 team_admin (또는 그 이상) 권한이 필요합니다 — developer 가 → Suppressed 전이 를 포함한 bulk 요청을 submit 하면 해당 행들은 forbidden(status_code: 403)으로 보고되고, 같은 submit 의 다른 행들은 정상 완료됩니다.
EPSS — 악용 확률
포털은 EPSS(Exploit Prediction Scoring System) score를 CVSS 옆에 노출해, 심각한 CVE와 실제 공격받을 가능성이 높은 CVE를 구분할 수 있게 합니다.
EPSS vs. CVSS — 각각 무엇을 답하나
- CVSS는 심각도를 측정합니다 — CVE가 악용되었을 때의 이론적 영향. 누군가 실제로 악용하는지, 할 것인지는 말하지 않습니다.
- EPSS는 향후 30일 내 실제 악용 확률을
0~1사이의 숫자로 측정합니다.
둘은 보완 관계입니다. CVSS 9.8(Critical)인데 EPSS는 0.01인 CVE — 문서상으로는 심각하지만 공격받을 예측 확률은 낮은 — 가 흔합니다. EPSS로 정렬·필터하면 실제로 위험한 소수의 결과에 집중하고 노이즈를 줄일 수 있습니다.
EPSS 데이터는 Trivy DB에서 옵니다 — Trivy가 EPSS 값을 제공하는 CVE에 한해서만 존재합니다. EPSS 값이 없는 결과는 UI에서 —, API에서 null로 표시됩니다 — 누락된 EPSS는 "낮음"이 아니라 "알 수 없음"으로 다루세요. EPSS는 CVSS나 VEX 분류를 대체하지 않으며, 하나의 추가 신호입니다.
포털의 EPSS 표시 방식
- Score — 백분율로 렌더링. EPSS
0.973은97.3%로 표시됩니다. - Percentile — "상위 N%"로 렌더링. 99번째 백분위수의 결과는 대략 "상위 1%"로 표시되며, 그 점수가 전체 채점된 CVE의 약 99%보다 높음을 뜻합니다.
- 누락 —
—(Trivy DB가 해당 CVE에 EPSS 값을 제공하지 않음).
score와 percentile은 결과 테이블의 EPSS 컬럼과 드로어의 요약(Summary) 섹션에 나타납니다.