보안 보고서 수집 개요

경고:
Vulnerability::Feedback 모델은 현재 사용 중단(deprecation) 상태이며, 모든 향후 개발에서 적극적으로 피해야 합니다. 현재는 이 이슈가 발생할 경우를 대비하여 기능 동등성을 유지하며 유지 관리되고 있지만, 16.0에서 제거될 예정입니다. Feedback 모델과 관련된 모든 상호 작용은 StateTransition, IssueLink, 및 MergeRequestLink 모델에 의해 대체됩니다. 이 에픽에서 더 많은 정보를 찾을 수 있습니다.

일반적으로 사용되는 용어

Feedback

Vulnerabilities::Feedback 클래스의 인스턴스입니다. 이들은 취약점으로 승격되기 전에 사용자의 취약점 발견과의 상호 작용을 추적하기 위해 생성됩니다. 이 모델은 사용 중단 상태이며 GitLab 16.0에서 제거될 예정입니다(Vulnerabilities::Feedback 에픽에서 사용 중단 및 제거).

Vulnerabilities::IssueLink 클래스의 인스턴스입니다. 이들은 Vulnerability 레코드를 Issue 레코드에 연결하는 데 사용됩니다.

Vulnerabilities::MergeRequestLink 클래스의 인스턴스입니다. 이들은 Vulnerability 레코드를 Merge Request 레코드에 연결하는 데 사용됩니다.

Security Finding

Security::Finding 클래스의 인스턴스입니다. 이들은 특정 보안 스캔에서 감지된 특정 취약점의 메타데이터 저장소 역할을 합니다. 현재 파이프라인 보안 보고서의 성능을 개선하기 위해 부분적 발견 데이터를 저장합니다. 이 클래스는 필요한 거의 모든 스캔 정보를 저장할 수 있도록 확장되었으며, 더 이상 작업 결과물에 의존하지 않도록 할 예정이며 Vulnerability::Findings 대신 사용될 예정입니다.

Security Scan

Security::Scan 클래스의 인스턴스입니다. 보안 스캔은 Job Artifact를 출력하여 보안 스캔 결과로 출력된 Ci::Build를 대표합니다. GitLab은 이를 인식하고 Security::Finding 레코드로 발견 사항을 수집합니다.

State Transition

Vulnerabilities::StateTransition 클래스의 인스턴스입니다. 이 모델은 해당 취약점 레코드의 상태 변경을 나타내며, 예를 들어 안전하다고 판단된 취약점을 기각하는 경우를 포함합니다.

Vulnerability

Vulnerability 클래스의 인스턴스입니다. Vulnerability는 프로젝트의 기본 브랜치에서 감지된 Vulnerability::Finding을 대표하며, present_on_default_branch 플래그가 false인 경우, 기본 브랜치 외부에서 어떤 방식으로든 상호작용이 이루어진 발견을 나타냅니다. 이는 기각되었거나(State Transition), Issue 또는 Merge Request에 링크되었을 수 있습니다. 이들은 Vulnerabilities::Finding 클래스에 있는 정보를 바탕으로 생성됩니다. 모든 Vulnerability는 유효하기 위해 반드시 해당하는 Vulnerabilities::Finding 객체를 가져야 하지만, 이는 데이터베이스 레벨에서 강제되지는 않습니다.

Finding

Vulnerabilities::Finding 클래스의 인스턴스입니다. Vulnerability::Finding은 프로젝트의 기본 브랜치에 병합된 보안 발견의 데이터베이스 전용 표현입니다. 동일한 Vulnerability가 프로젝트 내 여러 위치에 존재할 수 있습니다. 이 클래스는 이전에 Vulnerabilities::Occurrence라고 불렸으며, 클래스 이름을 변경한 후 큰 테이블 이름 변경 작업의 수고를 줄이기 위해 관련 테이블 이름 vulnerability_occurrences를 유지했습니다.

식별자

Vulnerabilities::Identifier 클래스의 인스턴스입니다. 각 취약점에는 고유한 식별자가 부여되며, 이는 발견된 내용에서 유도될 수 있어, 동일한 Vulnerability의 여러 발견이 적절하게 상관 관계를 가질 수 있습니다.

취약점 읽기

Vulnerabilities::Read 클래스의 인스턴스입니다. 이는 성능 향상을 위해 취약점 데이터에 대한 필터링된 쿼리의 비정규화된 VulnerabilityVulnerability::Finding 데이터 기록입니다.

수정 조치

Vulnerabilities::Remediation 클래스의 인스턴스입니다. 수정 조치는 발견된 Vulnerability에 대한 알려진 솔루션을 나타냅니다. 이를 통해 GitLab은 특정 Vulnerability를 해결하기 위한 변경을 권장할 수 있습니다.

보안 보고서에서의 취약점 생성

가정:

  • 프로젝트는 GitLab CI를 사용합니다.
  • 프로젝트는 보안 스캔 도구를 사용합니다.
  • 데이터베이스에 취약점이 없습니다.
  • 모든 파이프라인은 보안 스캔을 수행합니다.

비기본 브랜치에서 파이프라인의 스캔 실행

  1. 코드가 브랜치에 푸시됩니다.

  2. GitLab CI가 해당 브랜치에 대한 새로운 파이프라인을 실행합니다.

  3. 파이프라인 상태가 ::Ci::Pipeline.completed_statuses 중 하나로 전환됩니다.

  4. Security::StoreScansWorker가 호출되며 Security::StoreScansService를 예약합니다.

  5. Security::StoreScansServiceSecurity::StoreGroupedScansService를 호출하고 ScanSecurityReportSecretsWorker를 예약합니다.

  6. Security::StoreGroupedScansServiceSecurity::StoreScanService를 호출합니다.

  7. Security::StoreScanServiceSecurity::StoreFindingsService를 호출합니다.

  8. ScanSecurityReportSecretsWorkerSecurity::TokenRevocationService를 호출하여 감지된 유출된 키를 자동으로 폐기합니다.

이 시점에서는 Vulnerability 기록이 아닌 Security::Finding 기록만 있으며, 이는 이러한 발견이 프로젝트의 기본 브랜치에 존재하지 않기 때문입니다. 이러한 Security::Finding 기록이 Vulnerability 기록으로 승격될 수 있는 시나리오는 아래에 설명되어 있습니다.

기본 브랜치에서 파이프라인의 스캔 실행

파이프라인이 기본 브랜치에서 실행되었다면, 다음 단계가 실행됩니다. 이는 비기본 브랜치에서 파이프라인의 스캔 실행 단계에 추가됩니다.

  1. Security::StoreScansService가 호출되고 StoreSecurityReportsByProjectWorker를 예약합니다.

  2. StoreSecurityReportsByProjectWorkerSecurity::Ingestion::IngestReportsService를 실행합니다.

  3. Security::Ingestion::IngestReportsService는 주어진 파이프라인의 모든 보고서를 가져와 Security::Ingestion::IngestReportService를 호출하고 그 후 Security::Ingestion::MarkAsResolvedService를 호출합니다.

  4. Security::Ingestion::IngestReportServiceSecurity::Ingestion::IngestReportSliceService를 호출하여 보고서 슬라이스에 대한 여러 작업을 실행합니다.

기각

취약점의 상태를 변경하면, 예를 들어 Dismiss vulnerability를 선택하는 경우 현재 다음과 같은 일이 발생합니다.

  • 현재 상태를 기록하기 위해 dismissal 유형의 Feedback 기록이 생성됩니다.

  • 존재하지 않는 경우, present_on_default_branch: false 특성을 가진 Vulnerability FindingVulnerability가 생성되며, 상태 변경을 반영하는 State Transition이 관련됩니다.

상태 변경에 대한 댓글을 선택적으로 추가할 수 있으며, 이는 FeedbackState Transition 모두에 기록됩니다.

문제 또는 병합 요청 생성

문제 생성 또는 병합 요청 생성을 선택하면 현재 다음과 같은 일이 발생합니다:

  • Vulnerabilities::Feedback 레코드가 생성됩니다. 피드백은 feedback_typeissue 또는 merge request이고, 첨부 파일에 따라 issue_id 또는 merge_request_idNULL이 아닙니다.
  • 존재하지 않는 경우, present_on_default_branch: false 속성을 가진 Vulnerability FindingVulnerability가 생성되며, 해당 작업에 따라 Issue Link 또는 Merge Request Link가 관련됩니다.

기본 브랜치의 취약점

기본 브랜치에서 실행된 스캔에서 감지된 보안 발견 사항은 present_on_default_branch: true 속성을 가진 Vulnerabilities로 저장되며, 해당하는 Vulnerability Finding 레코드가 생성됩니다. 기본 브랜치 외부의 상호작용에서 이미 존재하는 Vulnerability 레코드는 present_on_default_branch: true로 업데이트됩니다.

이미 상호작용이 있었던 Vulnerabilities는 모든 기존 State Transitions, Merge Request Links, Issue Links, 및 해당하는 Vulnerability Feedback을 유지합니다.

취약점 읽기 생성

Vulnerability::Read 레코드는 Vulnerability::Finding 레코드가 생성될 때 PostgreSQL 데이터베이스 트리거를 통해 생성되며, 이에 따라 우리의 수집 프로세스의 일부가 되지만, 보고서 페이지의 비정규화 성능 이외에는 영향을 미치지 않습니다.

이러한 생성 방식은 빠르고 원활하게 이루어지도록 의도되었으나, 디버깅 및 유지 관리가 어렵다는 것이 입증되었으며, 나중에 애플리케이션 레이어로 마이그레이션될 수 있습니다.

더 이상 감지되지 않음

취약점 보고서의 “더 이상 감지되지 않음” 배지는 Vulnerability 레코드의 resolved_on_default_branch: true일 때 표시됩니다. 이는 기본 브랜치에서 파이프라인이 실행될 때 Security::Ingestion::MarkAsResolvedService에 의해 설정됩니다. resolved_on_default_branch: false이고 파이프라인 스캔 결과에 존재하지 않는 취약점은 해결된 것으로 표시됩니다.

비밀 탐지수동 취약점은 이 프로세스에서 제외됩니다.