보안 보고서 수집 개요
GitLab v19.1Vulnerability::Feedback 모델은 현재 지원 중단(deprecation) 절차를 진행 중이며, 이후 모든 개발에서 적극적으로 사용을 피해야 합니다. Vulnerabilities::Feedback 클래스의 인스턴스입니다.
Vulnerability::Feedback 모델은 현재 지원 중단(deprecation) 절차를 진행 중이며, 이후 모든 개발에서 적극적으로 사용을 피해야 합니다. 현재는 문제가 발생할 경우 되돌릴 수 있도록 동등한 기능 수준을 유지하고 있지만, 16.0에서 제거될 예정입니다. Feedback 모델과 관련된 모든 인터랙션은 StateTransition, IssueLink, MergeRequestLink 모델로 대체됩니다. 자세한 내용은 이 에픽에서 확인하실 수 있습니다.
자주 사용되는 용어#
Feedback#
Vulnerabilities::Feedback 클래스의 인스턴스입니다. Vulnerability Findings가 Vulnerability로 승격되기 전에 사용자와의 인터랙션을 추적하기 위해 생성됩니다. 이 모델은 지원 중단(deprecated) 상태이며, Deprecate and remove Vulnerabilities::Feedback 에픽의 일환으로 GitLab 16.0까지 제거될 예정입니다.
Issue Link#
Vulnerabilities::IssueLink 클래스의 인스턴스입니다. Vulnerability 레코드를 Issue 레코드에 연결하는 데 사용됩니다.
Merge Request Link#
Vulnerabilities::MergeRequestLink 클래스의 인스턴스입니다. Vulnerability 레코드를 MergeRequest 레코드에 연결하는 데 사용됩니다.
Security Finding#
Security::Finding 클래스의 인스턴스입니다. 특정 Security::Scan에서 탐지된 특정 취약점의 메타데이터 저장소 역할을 합니다. 파이프라인 보안 보고서, pipeline.securityReportFindings GraphQL 필드, Vulnerability Findings REST API에 필요한 모든 스캔 정보를 저장합니다.
Security Scan#
Security::Scan 클래스의 인스턴스입니다. Security Scan은 보안 스캔 결과로 출력된 Job Artifact를 생성한 Ci::Build를 나타내며, GitLab은 이를 인식하고 Security::Finding 레코드로 findings를 수집합니다.
State Transition#
Vulnerabilities::StateTransition 클래스의 인스턴스입니다. 이 모델은 해당 Vulnerability 레코드의 상태 변경을 나타냅니다. 예를 들어 안전하다고 판단된 취약점의 해제(dismissal)가 이에 해당합니다.
Vulnerability#
Vulnerability 클래스의 인스턴스입니다. Vulnerability는 프로젝트의 기본 브랜치에서 탐지된 Vulnerabilities::Finding 레코드를 나타내며, present_on_default_branch 플래그가 false인 경우에는 기본 브랜치 외부에서 어떤 방식으로든 인터랙션이 발생한 finding을 나타냅니다. 예를 들어 해제(State Transition)되거나 Issue 또는 Merge Request에 연결된 경우입니다. Vulnerabilities::Finding 클래스에서 사용 가능한 정보를 기반으로 생성됩니다. 모든 Vulnerability는 유효하기 위해 대응하는 Vulnerabilities::Finding 객체를 반드시 가져야 하지만, 이는 데이터베이스 수준에서 강제되지 않습니다.
Vulnerability Finding#
Vulnerabilities::Finding 클래스의 인스턴스입니다. Vulnerabilities::Finding 레코드는 프로젝트의 기본 브랜치에 병합된 보안 finding의 데이터베이스 전용 표현이며, 동일한 Vulnerability가 프로젝트 내 여러 위치에 존재할 수 있기 때문입니다. 이 클래스는 이전에 Vulnerabilities::Occurrence로 불렸으며, 클래스 이름을 변경한 후 대형 테이블 이름 변경에 드는 노력 때문에 연결된 테이블 이름 vulnerability_occurrences는 유지했습니다.
Identifier#
Vulnerabilities::Identifier 클래스의 인스턴스입니다. 각 취약점에는 finding에서 도출할 수 있는 고유 식별자가 부여되어, 동일한 Vulnerability의 여러 Findings가 적절히 상관될 수 있습니다.
Vulnerability Read#
Vulnerabilities::Read 클래스의 인스턴스입니다. 이는 취약점 데이터의 필터링된 쿼리 성능을 프론트엔드에서 개선하기 위해 Vulnerability 및 Vulnerabilities::Finding 데이터를 비정규화한 레코드입니다.
Remediation#
Vulnerabilities::Remediation 클래스의 인스턴스입니다. Remediation은 탐지된 Vulnerability에 대한 알려진 해결책을 나타냅니다. 이를 통해 GitLab은 특정 Vulnerability를 해결하기 위한 변경 사항을 권장할 수 있습니다.
보안 보고서로부터 취약점 생성#
전제 조건:
-
프로젝트가 GitLab CI를 사용합니다.
-
프로젝트가 보안 스캐닝 도구를 사용합니다.
-
데이터베이스에 취약점이 없습니다.
-
모든 파이프라인이 보안 스캔을 수행합니다.
비기본 브랜치의 파이프라인에서 스캔 실행#
-
브랜치에 코드가 푸시됩니다.
-
GitLab CI가 해당 브랜치에 대해 새 파이프라인을 실행합니다.
-
파이프라인 상태가
::Ci::Pipeline.completed_statuses중 하나로 전환됩니다. -
Security::StoreScansWorker가 호출되고Security::StoreScansService를 스케줄링합니다. -
Security::StoreScansService가Security::StoreGroupedScansService를 호출하고ScanSecurityReportSecretsWorker를 스케줄링합니다. -
Security::StoreGroupedScansService가Security::StoreScanService를 호출합니다. -
Security::StoreScanService가Security::StoreFindingsService를 호출합니다. -
ScanSecurityReportSecretsWorker가Security::TokenRevocationService를 호출하여 탐지된 유출된 키를 자동으로 폐기합니다.
이 시점에서는 findings가 프로젝트의 기본 브랜치에 없기 때문에 Vulnerability 레코드가 아닌 Security::Finding 레코드만 존재합니다.
이러한 Security::Finding 레코드가 Vulnerability 레코드로 승격될 수 있는 일부 시나리오는 아래에 설명되어 있습니다.
기본 브랜치의 파이프라인에서 스캔 실행#
파이프라인이 기본 브랜치에서 실행된 경우, 비기본 브랜치의 파이프라인에서 스캔 실행 단계에 추가로 다음 단계가 실행됩니다:
-
Security::StoreScansService가 호출되고StoreSecurityReportsByProjectWorker를 스케줄링합니다. -
StoreSecurityReportsByProjectWorker가Security::Ingestion::IngestReportsService를 실행합니다. -
Security::Ingestion::IngestReportsService는 주어진 파이프라인의 모든 보고서를 가져와Security::Ingestion::IngestReportService를 호출한 다음Security::Ingestion::MarkAsResolvedService를 호출합니다. -
Security::Ingestion::IngestReportService는Security::Ingestion::IngestReportSliceService를 호출하며, 이는 보고서 슬라이스에 대해 여러 작업을 실행합니다.
해제(Dismissal)#
취약점 해제를 선택하는 등 취약점의 상태를 변경하면 현재 다음과 같은 일이 발생합니다:
-
현재 상태를 기록하기 위해
dismissal유형의Feedback레코드가 생성됩니다. -
아직 존재하지 않는 경우,
present_on_default_branch: false속성을 가진Vulnerability Finding과Vulnerability가 생성되며, 상태 변경을 반영하는State Transition이 이와 연결됩니다.
상태 변경에 선택적으로 댓글을 추가할 수 있으며, 이는 Feedback과 State Transition 모두에 기록됩니다.
이슈 또는 머지 리퀘스트 생성#
이슈 생성 또는 머지 리퀘스트 생성을 선택하면 현재 다음과 같은 일이 발생합니다:
-
Vulnerabilities::Feedback레코드가 생성됩니다. Feedback은issue또는merge request의feedback_type을 가지며, 첨부에 따라NULL이 아닌issue_id또는merge_request_id를 가집니다. -
아직 존재하지 않는 경우,
present_on_default_branch: false속성을 가진Vulnerability Finding과Vulnerability가 생성되며, 수행된 작업에 따라Issue Link또는Merge Request Link가 이와 연결됩니다.
기본 브랜치의 취약점#
기본 브랜치에서 실행된 스캔에서 탐지된 Security Findings는 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::Read 레코드는 Vulnerabilities::Finding 레코드 생성 시 PostgreSQL 데이터베이스 트리거를 통해 생성되므로 수집 프로세스의 일부이지만, 보고서 페이지에서의 비정규화 성능 이점 외에는 수집 프로세스에 영향을 미치지 않습니다.
이 생성 방식은 빠르고 원활하게 설계되었으나, 디버그 및 유지 관리가 어렵다는 것이 증명되었으며 나중에 애플리케이션 레이어로 마이그레이션될 수 있습니다.
더 이상 탐지되지 않음#
취약점 보고서의 "더 이상 탐지되지 않음" 배지는 Vulnerability 레코드의 resolved_on_default_branch: true인 경우 표시됩니다.
이는 파이프라인이 기본 브랜치에서 실행될 때 Security::Ingestion::MarkAsResolvedService에 의해 설정됩니다. resolved_on_default_branch: false이고 파이프라인 스캔 결과에 없는 취약점은 해결된 것으로 표시됩니다.
시크릿 탐지 및 수동 취약점은 이 프로세스에서 제외됩니다.