패키지 기반 취약점 억제
패키지 기반 취약점 억제(Package Vulnerability Suppression)는 패키지 URL(Package URL, PURL) 등으로 소프트웨어 패키지를 식별하고, 지정한 취약점 조건과 적용 범위를 함께 만족하는 발견 사항(Finding)을 억제합니다. 같은 패키지에서 CVE가 계속 발견되는 경우, CVE마다 별도 요청을 만드는 대신 패키지에 대한 위험 수용 규칙을 관리할 수 있습니다.
규칙은 현재와 향후 검사에 적용됩니다. 패키지가 이미지의 어느 계층에 있는지는 적용을 제한하지 않지만, 적용 범위와 패키지 조건, 취약점 조건은 모두 일치해야 합니다. 모든 요청에는 근거와 만료일이 필요하며 변경 요청(Change request)의 승인을 받아야 합니다.
발견 사항과 상태
발견 사항은 검사한 이미지에 나타난 패키지와 CVE의 조합입니다. 상태는 SLA를 기준으로 유예기간 안에 있는지, 기한이 지났는지, 억제되었는지를 보여 줍니다. 변경 요청이 진행 중이면 억제 대기 표시가 나타납니다.
패키지 기반 억제는 사용자가 요청하는 억제에 속합니다. 유예기간 억제는 취약점이 처음 발견된 때부터 시작하는 별도 기한이며 검사마다 갱신되지 않습니다. 억제는 이후 검사에서 발견 사항을 지우지 않고, 해당 발견 사항을 이유로 릴리스를 회수하는 동작을 제한합니다.
PURL로 패키지 식별
PURL의 기본 형태는 pkg:type/namespace/name입니다.
| 부분 | 의미와 예시 |
|---|---|
type | 패키지 생태계입니다. rpm, deb, golang, npm, maven 등이 있습니다. |
namespace | 생태계 안의 묶음입니다. pkg:rpm/redhat/perl-overload에서는 redhat, pkg:golang/golang.org/x/sys에서는 golang.org/x입니다. |
name | 해당 생태계와 네임스페이스 안의 패키지 이름입니다. 위 예시에서는 perl-overload와 sys입니다. |
같은 coreutils라도 pkg:rpm/redhat/coreutils, pkg:deb/ubuntu/coreutils, pkg:rpm/suse/coreutils는 서로 다른 패키지입니다. 네임스페이스가 없는 pkg:npm/lodash 같은 PURL도 있습니다. 패키지는 운영체제 계층에 포함될 수도 있고 애플리케이션이 별도로 추가할 수도 있습니다.
Package URLs에 입력할 때는 type, namespace, name만 지정합니다. @1.2.3 같은 버전, ?arch=x86_64 같은 한정자(qualifier), # 뒤의 하위 경로는 PURL 입력에서 제외합니다. 버전과 한정자는 각각 별도 조건으로 설정합니다.
시작 조건과 양식 진입
Risk Management 접근 권한과 취약점 억제 생성 권한이 필요합니다. 승인자는 Settings & Configuration → Permissions → Vulnerability suppressions의 Approver 역할로 설정합니다.
Applications → Risk Management를 엽니다.
Vulnerabilities에서 발견 사항을 찾거나 오른쪽 위 Actions 메뉴에서 생성 양식을 직접 엽니다. 제품 릴리스의 Security 화면과 번들의 Security 화면에서도 진입할 수 있습니다.
Actions에는 Create vulnerability suppression과 Download all suppressions as a CSV가 있습니다.
Rules: 적용 범위
가능하면 필요한 발견 사항만 포함하는 좁은 범위를 선택합니다.
| Scope | 적용 대상 |
|---|---|
| Image repository | 지정한 이미지 저장소 이름과 정확히 일치하는 대상입니다. 기본값이며 가장 좁은 선택입니다. |
| Product | 하나 이상의 제품에서 선택한 SLS 버전입니다. |
| SLS distribution | 하나 이상의 제품 ID에 해당하는 SLS 배포물입니다. |
| Image prefix | 지정한 접두사 중 하나로 시작하는 이미지 저장소입니다. Advanced options에서 선택합니다. |
| Global | 조직의 모든 아티팩트입니다. Advanced options에서 선택하며 더 넓은 위험 검토가 필요합니다. |
Image repository의 Image repositories에는 하나 이상의 저장소 이름을 추가합니다. 비교할 때는 레지스트리와 태그 또는 다이제스트를 제거한 저장소 이름을 사용합니다. 예를 들어 team/service를 입력합니다. 범위를 바꾸어도 승인자나 승인 경로는 바뀌지 않으며 검토할 위험 범위가 달라집니다.
Rules: 취약점 조건
Vulnerabilities → Vulnerability matcher에서 직접 ID를 지정하거나 속성 조건을 구성합니다.
Explicit vulnerability IDs
스캐너가 보고한 식별자와 정확히 일치하는 취약점만 선택합니다. Vulnerability IDs에 예시 값 CVE-2024-0056처럼 각 ID를 추가합니다.
Match by properties
선택한 모든 속성 그룹을 만족해야 합니다. 같은 그룹 안에서 여러 값을 선택하면 그중 하나와 일치하면 됩니다. 이 규칙은 같은 특성의 향후 CVE에도 적용됩니다.
| 속성 그룹 | 선택값과 판정 |
|---|---|
| Severities | Critical, High, Medium, Low, Unspecified 가운데 선택한 심각도 중 하나 |
| Sources | Library package 또는 OS package 중 선택한 유형 |
| Fix statuses | Not fixed, Fixed, Won't fix 중 선택한 수정 상태 |
| Known exploitation | Known to be actively exploited 또는 Not known to be actively exploited 중 선택한 실제 악용 여부 |
| Excluded vulnerability IDs | 여기에 추가한 ID는 다른 조건을 모두 충족해도 제외 |
예를 들어 수정본이 없는 발견 사항을 대상으로 하려면 Not fixed와 Won't fix를 선택합니다. 낮은 심각도만 허용하려면 해당 심각도만 선택합니다. 각 규칙에는 나머지 속성 그룹과 적용 범위도 함께 설정해야 합니다.
Rules: 패키지 조건
패키지는 이름 조건, 버전 조건, 설정한 모든 한정자 조건을 충족해야 합니다.
| Package name matcher | 의미 |
|---|---|
| All packages | 모든 패키지를 선택합니다. 취약점 조건과 적용 범위만으로 위험이 충분히 제한될 때 사용합니다. |
| Package URL | 하나 이상의 PURL에 해당하는 패키지를 선택합니다. |
| Package namespace URL | 네임스페이스 안에서 게시된 모든 패키지를 선택합니다. 운영체제 공급자별 패키지 선택 등에 사용할 수 있습니다. |
| Upstream package name | 상위 패키지 이름으로 선택합니다. |
| Package version matcher | 의미 |
|---|---|
| All versions | 모든 버전 |
| Exact versions | 입력한 정확한 버전만 |
| SLS version ranges | 지정한 SLS 버전 범위에 속하는 버전 |
Package qualifiers로 아키텍처 같은 한정자를 추가하여 범위를 좁힐 수 있습니다. Package URL을 선택하면 Package URLs에 버전, 한정자와 하위 경로를 제외한 PURL을 추가합니다.
패키지 하나의 모든 CVE를 억제하려면 해당 PURL과 모든 심각도를 포함하는 취약점 조건을 사용합니다. 이 경우에도 다른 속성 조건과 범위가 실제 의도와 맞는지 확인해야 합니다.
사유 분류와 필수 설명
| Suppression category | 사용 조건과 필요한 증거 |
|---|---|
| False positive | 스캐너가 제품에 실제로 존재하지 않는 취약점을 잘못 탐지했습니다. 오탐임을 입증하는 문서와 증거가 필요합니다. 구성 요소의 존재를 정확히 탐지했지만 제품이 영향을 받지 않는다는 이유만으로 이 분류를 사용하지 않습니다. |
| Won't fix | 제품의 운영 요구 때문에 발견 사항을 수정할 수 없거나 수정하지 않기로 했습니다. 취약점 악용을 막는 완화 통제의 증거가 필요합니다. |
| Vendor dependency | 상위 의존성에 취약점이 있으나 공급자가 패치를 제공하지 않았습니다. 수정본이 없음을 조사한 근거가 필요합니다. |
| Planned fix | 공급자가 수정을 계획하고 릴리스 일정을 정했습니다. 공급자 권고문이나 수정 추적 이슈처럼 계획을 확인할 증거가 필요합니다. |
분류에 따라 필수 질문이 달라집니다. 즉시 수정할 수 없는 구체적인 이유, 수정 방법, 목표 수정일과 필요한 단계, 그동안 악용 위험을 줄이는 보안 통제를 설명합니다. 네트워크 제한, 모니터링, 방화벽, 사용 제한, 실행하지 않는 코드 경로, 인증 뒤에 있는 기능 등을 해당 환경의 사실과 함께 기록합니다.
Expiration은 필수입니다. 1 week, 3 months, 1 year 같은 프리셋이나 Custom date를 선택합니다. 만료일은 목표 수정일과 맞추며 무기한 억제는 만들 수 없습니다.
Verification: 예상 영향 확인
제출 전에 규칙이 선택할 발견 사항을 검토합니다. 표에는 CVE, 발견 사항이 있는 Releases, PURL로 식별한 Package가 표시됩니다. 의도하지 않은 패키지나 릴리스가 포함되어 있으면 규칙을 좁힙니다.
Placement: 규칙을 넣을 억제 선택
Apollo는 규칙을 기존 억제에 추가할지 새 억제를 만들지 제안합니다. 각 규칙의 배치를 확인하고 Suppression ID와 Description을 필요에 따라 수정합니다.
Use one suppression ID and description for all Create New rules를 선택하면 새 억제를 만드는 모든 규칙에 같은 ID와 설명을 적용합니다. 변경 요청은 억제별로 생성되므로 규칙을 적절히 묶으면 승인할 요청 수를 줄일 수 있습니다. 서로 다른 위험 근거를 단지 요청 수를 줄이기 위해 합치지는 않습니다.
요청 생성과 검토 결과
요청을 열면 억제마다 변경 요청 하나를 생성합니다. 각 요청은 별도로 검토하고 승인해야 합니다.
승인된 발견 사항은 다음 검사에서 억제 상태로 바뀝니다. 거절되면 발견 사항이 목록에 남아 후속 조치 대상이 됩니다. 각 요청에는 검토자가 판단할 수 있는 명확한 근거와 만료일이 있어야 하며, 결정과 변경 이력은 감사 기록으로 남습니다.