InfoGrab DocsInfoGrab Docs

보안 보고서 수집 개요

요약

Vulnerability::Feedback 모델은 현재 지원 중단 절차를 밟고 있으므로 이후 개발에서는 사용하지 않아야 합니다. Vulnerabilities::Feedback 클래스의 인스턴스입니다. Vulnerabilities::IssueLink 클래스의 인스턴스입니다.

Warning

Vulnerability::Feedback 모델은 현재 지원 중단 절차를 밟고 있으므로 이후 개발에서는 사용하지 않아야 합니다. 문제가 생겼을 때 되돌릴 수 있도록 지금은 기능 동등성을 유지하고 있으나, 16.0에서 제거할 예정입니다. Feedback 모델과 관련된 상호작용은 모두 StateTransition, IssueLink, MergeRequestLink 모델로 대체됩니다. 자세한 내용은 이 에픽에서 확인할 수 있습니다.

자주 사용되는 용어#

Feedback#

Vulnerabilities::Feedback 클래스의 인스턴스입니다. Vulnerability Finding 이 Vulnerability로 승격되기 전에 사용자가 그와 상호작용한 내역을 추적하기 위해 생성됩니다. 이 모델은 지원이 중단되었으며 Vulnerabilities::Feedback 지원 중단 및 제거 에픽의 일부로 제거될 예정입니다.

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

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 레코드로 수집합니다.

State Transition#

Vulnerabilities::StateTransition 클래스의 인스턴스입니다. 이 모델은 해당 Vulnerability 레코드의 상태 변경을 나타내며, 안전하다고 판단된 취약점을 해제하는 경우가 그러한 예입니다.

Vulnerability#

Vulnerability 클래스의 인스턴스입니다. Vulnerability는 프로젝트의 기본 브랜치에서 탐지된 Vulnerabilities::Finding 레코드를 나타냅니다. present_on_default_branch 플래그가 false 라면, 해제(State Transition)되거나 Issue 또는 Merge Request에 연결되는 등 기본 브랜치 밖에서 어떤 방식으로든 상호작용이 있었던 발견 항목을 나타냅니다. Vulnerabilities::Finding 클래스에서 얻을 수 있는 정보를 바탕으로 생성됩니다. 모든 Vulnerability는 유효하려면 대응하는 Vulnerabilities::Finding 객체를 반드시 가져야 하지만, 이는 데이터베이스 수준에서 강제되지 않습니다.

Vulnerability Finding#

Vulnerabilities::Finding 클래스의 인스턴스입니다. Vulnerabilities::Finding 레코드는 프로젝트의 기본 브랜치에 머지된 보안 발견 항목을 데이터베이스에만 표현한 것입니다. 같은 Vulnerability가 프로젝트 안 여러 곳에 존재할 수 있기 때문입니다. 이 클래스는 이전에 Vulnerabilities::Occurrence로 불렸으며, 클래스 이름을 바꾼 뒤에도 큰 테이블의 이름을 바꾸는 데 드는 노력 때문에 연관 테이블 이름은 vulnerability_occurrences로 유지했습니다.

Identifier#

Vulnerabilities::Identifier 클래스의 인스턴스입니다. 각 취약점에는 발견 항목에서 도출할 수 있는 고유 식별자가 부여되며, 이를 통해 같은 Vulnerability의 여러 Finding을 서로 연관 지을 수 있습니다.

Vulnerability Read#

Vulnerabilities::Read 클래스의 인스턴스입니다. Vulnerability와 Vulnerabilities::Finding 데이터를 비정규화한 레코드로, 프론트엔드로 보낼 취약점 데이터의 필터링 쿼리 성능을 높입니다.

Remediation#

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

보안 리포트로부터 취약점 생성#

전제는 다음과 같습니다.

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

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

  1. 브랜치에 코드가 푸시됩니다.
  2. GitLab CI가 해당 브랜치의 새 파이프라인을 실행합니다.
  3. 파이프라인 상태가 ::Ci::Pipeline.completed_statuses 중 하나로 전환됩니다.
  4. Security::StoreScansWorker가 호출되어 Security::StoreScansService를 예약합니다.
  5. Security::StoreScansService가 Security::StoreGroupedScansService를 호출하고 ScanSecurityReportSecretsWorker를 예약합니다.
  6. Security::StoreGroupedScansService가 Security::StoreScanService를 호출합니다.
  7. Security::StoreScanService가 Security::StoreFindingsService를 호출합니다.
  8. ScanSecurityReportSecretsWorker가 Security::TokenRevocationService를 호출하여 탐지된 유출 키를 자동으로 폐기합니다.

이 시점에는 해당 발견 항목이 프로젝트의 기본 브랜치에 없으므로 Vulnerability 레코드가 아닌 Security::Finding 레코드만 존재합니다. 이러한 Security::Finding 레코드가 Vulnerability 레코드로 승격되는 시나리오는 아래에서 설명합니다.

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

파이프라인이 기본 브랜치에서 실행되었다면 기본 브랜치가 아닌 브랜치의 파이프라인에서 스캔 실행의 단계에 더해 다음 단계가 실행됩니다.

  1. Security::StoreScansService가 호출되어 StoreSecurityReportsByProjectWorker를 예약합니다.
  2. StoreSecurityReportsByProjectWorker가 Security::Ingestion::IngestReportsService를 실행합니다.
  3. Security::Ingestion::IngestReportsService가 해당 파이프라인의 모든 리포트를 받아 Security::Ingestion::IngestReportService를 호출한 다음 Security::Ingestion::MarkAsResolvedService를 호출합니다.
  4. Security::Ingestion::IngestReportService가 Security::Ingestion::IngestReportSliceService를 호출하며, 이 서비스는 리포트 슬라이스에 대한 여러 작업을 실행합니다.

해제#

Dismiss vulnerability를 선택하는 등 취약점의 상태를 변경하면 현재 다음과 같은 일이 일어납니다.

  • 현재 상태를 기록하기 위해 dismissal 유형의 Feedback 레코드가 생성됩니다.
  • 아직 없다면 Vulnerability Finding과 present_on_default_branch: false 속성을 가진 Vulnerability가 생성되고, 상태 변경을 반영하는 State Transition이 여기에 연결됩니다.

상태 변경에 댓글을 덧붙일 수도 있으며, 이 댓글은 Feedback과 State Transition 양쪽에 기록됩니다.

이슈 또는 머지 리퀘스트 생성#

Create issue 나 Create merge request를 선택하면 현재 다음과 같은 일이 일어납니다.

  • Vulnerabilities::Feedback 레코드가 생성됩니다. 이 Feedback은 feedback_type이 issue 또는 merge request이고, 연결 대상에 따라 NULL이 아닌 issue_id 또는 merge_request_id를 가집니다.
  • 아직 없다면 Vulnerability Finding과 present_on_default_branch: false 속성을 가진 Vulnerability가 생성되고, 수행한 작업에 따라 Issue Link 또는 Merge Request Link가 여기에 연결됩니다.

기본 브랜치의 취약점#

기본 브랜치에서 실행된 스캔이 탐지한 Security Finding은 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 데이터베이스 트리거로 만들어지므로 수집 과정의 일부이지만, 리포트 페이지에서의 비정규화 성능 이점을 제외하면 수집 과정 자체에는 영향을 주지 않습니다.

이 생성 방식은 빠르고 매끄럽게 동작하도록 의도했으나 디버깅과 유지 보수가 어렵다는 점이 드러났으며, 이후 애플리케이션 계층으로 옮길 수 있습니다.

더 이상 탐지되지 않음#

취약점 리포트의 "No longer detected" 배지는 Vulnerability 레코드에 resolved_on_default_branch: true가 설정된 경우에 표시됩니다. 이 값은 기본 브랜치에서 파이프라인이 실행될 때 Security::Ingestion::MarkAsResolvedService가 설정합니다. resolved_on_default_branch: false이면서 파이프라인 스캔 결과에 없는 취약점은 해결됨으로 표시됩니다. 시크릿 탐지와 수동으로 추가한 취약점은 이 과정에서 제외됩니다.

보안 보고서 수집 개요

GitLab v19.4
원문 보기

요약

Vulnerability::Feedback 모델은 현재 지원 중단 절차를 밟고 있으므로 이후 개발에서는 사용하지 않아야 합니다. Vulnerabilities::Feedback 클래스의 인스턴스입니다. Vulnerabilities::IssueLink 클래스의 인스턴스입니다.

Warning

Vulnerability::Feedback 모델은 현재 지원 중단 절차를 밟고 있으므로 이후 개발에서는 사용하지 않아야 합니다. 문제가 생겼을 때 되돌릴 수 있도록 지금은 기능 동등성을 유지하고 있으나, 16.0에서 제거할 예정입니다. Feedback 모델과 관련된 상호작용은 모두 StateTransition, IssueLink, MergeRequestLink 모델로 대체됩니다. 자세한 내용은 이 에픽에서 확인할 수 있습니다.

자주 사용되는 용어#

Feedback#

Vulnerabilities::Feedback 클래스의 인스턴스입니다. Vulnerability Finding 이 Vulnerability로 승격되기 전에 사용자가 그와 상호작용한 내역을 추적하기 위해 생성됩니다. 이 모델은 지원이 중단되었으며 Vulnerabilities::Feedback 지원 중단 및 제거 에픽의 일부로 제거될 예정입니다.

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

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 레코드로 수집합니다.

State Transition#

Vulnerabilities::StateTransition 클래스의 인스턴스입니다. 이 모델은 해당 Vulnerability 레코드의 상태 변경을 나타내며, 안전하다고 판단된 취약점을 해제하는 경우가 그러한 예입니다.

Vulnerability#

Vulnerability 클래스의 인스턴스입니다. Vulnerability는 프로젝트의 기본 브랜치에서 탐지된 Vulnerabilities::Finding 레코드를 나타냅니다. present_on_default_branch 플래그가 false 라면, 해제(State Transition)되거나 Issue 또는 Merge Request에 연결되는 등 기본 브랜치 밖에서 어떤 방식으로든 상호작용이 있었던 발견 항목을 나타냅니다. Vulnerabilities::Finding 클래스에서 얻을 수 있는 정보를 바탕으로 생성됩니다. 모든 Vulnerability는 유효하려면 대응하는 Vulnerabilities::Finding 객체를 반드시 가져야 하지만, 이는 데이터베이스 수준에서 강제되지 않습니다.

Vulnerability Finding#

Vulnerabilities::Finding 클래스의 인스턴스입니다. Vulnerabilities::Finding 레코드는 프로젝트의 기본 브랜치에 머지된 보안 발견 항목을 데이터베이스에만 표현한 것입니다. 같은 Vulnerability가 프로젝트 안 여러 곳에 존재할 수 있기 때문입니다. 이 클래스는 이전에 Vulnerabilities::Occurrence로 불렸으며, 클래스 이름을 바꾼 뒤에도 큰 테이블의 이름을 바꾸는 데 드는 노력 때문에 연관 테이블 이름은 vulnerability_occurrences로 유지했습니다.

Identifier#

Vulnerabilities::Identifier 클래스의 인스턴스입니다. 각 취약점에는 발견 항목에서 도출할 수 있는 고유 식별자가 부여되며, 이를 통해 같은 Vulnerability의 여러 Finding을 서로 연관 지을 수 있습니다.

Vulnerability Read#

Vulnerabilities::Read 클래스의 인스턴스입니다. Vulnerability와 Vulnerabilities::Finding 데이터를 비정규화한 레코드로, 프론트엔드로 보낼 취약점 데이터의 필터링 쿼리 성능을 높입니다.

Remediation#

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

보안 리포트로부터 취약점 생성#

전제는 다음과 같습니다.

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

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

  1. 브랜치에 코드가 푸시됩니다.
  2. GitLab CI가 해당 브랜치의 새 파이프라인을 실행합니다.
  3. 파이프라인 상태가 ::Ci::Pipeline.completed_statuses 중 하나로 전환됩니다.
  4. Security::StoreScansWorker가 호출되어 Security::StoreScansService를 예약합니다.
  5. Security::StoreScansService가 Security::StoreGroupedScansService를 호출하고 ScanSecurityReportSecretsWorker를 예약합니다.
  6. Security::StoreGroupedScansService가 Security::StoreScanService를 호출합니다.
  7. Security::StoreScanService가 Security::StoreFindingsService를 호출합니다.
  8. ScanSecurityReportSecretsWorker가 Security::TokenRevocationService를 호출하여 탐지된 유출 키를 자동으로 폐기합니다.

이 시점에는 해당 발견 항목이 프로젝트의 기본 브랜치에 없으므로 Vulnerability 레코드가 아닌 Security::Finding 레코드만 존재합니다. 이러한 Security::Finding 레코드가 Vulnerability 레코드로 승격되는 시나리오는 아래에서 설명합니다.

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

파이프라인이 기본 브랜치에서 실행되었다면 기본 브랜치가 아닌 브랜치의 파이프라인에서 스캔 실행의 단계에 더해 다음 단계가 실행됩니다.

  1. Security::StoreScansService가 호출되어 StoreSecurityReportsByProjectWorker를 예약합니다.
  2. StoreSecurityReportsByProjectWorker가 Security::Ingestion::IngestReportsService를 실행합니다.
  3. Security::Ingestion::IngestReportsService가 해당 파이프라인의 모든 리포트를 받아 Security::Ingestion::IngestReportService를 호출한 다음 Security::Ingestion::MarkAsResolvedService를 호출합니다.
  4. Security::Ingestion::IngestReportService가 Security::Ingestion::IngestReportSliceService를 호출하며, 이 서비스는 리포트 슬라이스에 대한 여러 작업을 실행합니다.

해제#

Dismiss vulnerability를 선택하는 등 취약점의 상태를 변경하면 현재 다음과 같은 일이 일어납니다.

  • 현재 상태를 기록하기 위해 dismissal 유형의 Feedback 레코드가 생성됩니다.
  • 아직 없다면 Vulnerability Finding과 present_on_default_branch: false 속성을 가진 Vulnerability가 생성되고, 상태 변경을 반영하는 State Transition이 여기에 연결됩니다.

상태 변경에 댓글을 덧붙일 수도 있으며, 이 댓글은 Feedback과 State Transition 양쪽에 기록됩니다.

이슈 또는 머지 리퀘스트 생성#

Create issue 나 Create merge request를 선택하면 현재 다음과 같은 일이 일어납니다.

  • Vulnerabilities::Feedback 레코드가 생성됩니다. 이 Feedback은 feedback_type이 issue 또는 merge request이고, 연결 대상에 따라 NULL이 아닌 issue_id 또는 merge_request_id를 가집니다.
  • 아직 없다면 Vulnerability Finding과 present_on_default_branch: false 속성을 가진 Vulnerability가 생성되고, 수행한 작업에 따라 Issue Link 또는 Merge Request Link가 여기에 연결됩니다.

기본 브랜치의 취약점#

기본 브랜치에서 실행된 스캔이 탐지한 Security Finding은 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 데이터베이스 트리거로 만들어지므로 수집 과정의 일부이지만, 리포트 페이지에서의 비정규화 성능 이점을 제외하면 수집 과정 자체에는 영향을 주지 않습니다.

이 생성 방식은 빠르고 매끄럽게 동작하도록 의도했으나 디버깅과 유지 보수가 어렵다는 점이 드러났으며, 이후 애플리케이션 계층으로 옮길 수 있습니다.

더 이상 탐지되지 않음#

취약점 리포트의 "No longer detected" 배지는 Vulnerability 레코드에 resolved_on_default_branch: true가 설정된 경우에 표시됩니다. 이 값은 기본 브랜치에서 파이프라인이 실행될 때 Security::Ingestion::MarkAsResolvedService가 설정합니다. resolved_on_default_branch: false이면서 파이프라인 스캔 결과에 없는 취약점은 해결됨으로 표시됩니다. 시크릿 탐지와 수동으로 추가한 취약점은 이 과정에서 제외됩니다.