安全报告摄入概述
Vulnerability::Feedback 模型目前正在被弃用,应在所有后续开发中积极避免。目前它保持功能对等,以便在出现问题时可以回滚,但计划在 16.0 版本中移除。与 Feedback 模型相关的所有交互已被 StateTransition、IssueLink 和 MergeRequestLink 模型取代。您可以在这个 epic中了解更多信息。
常用术语
Feedback
Vulnerabilities::Feedback 类的实例。它们用于跟踪用户与漏洞发现(Vulnerability Findings)在被提升为漏洞(Vulnerability)之前的交互。此模型已被弃用,并计划在 GitLab 16.0 版本中移除,作为弃用并移除 Vulnerabilities::Feedback epic的一部分。
Issue Link
Vulnerabilities::IssueLink 类的实例。它们用于将 Vulnerability 记录链接到 Issue 记录。
Merge Request Link
Vulnerabilities::MergeRequestLink 类的实例。它们用于将 Vulnerability 记录链接到 MergeRequest 记录。
Security Finding
Security::Finding 类的实例。它们作为在特定 Security::Scan 中检测到的特定漏洞的元数据存储。它们目前存储部分发现数据以提高管道安全报告的性能。此类已扩展以存储几乎所有必需的扫描信息,因此我们可以停止依赖作业工件,并且即将被用来替代 Vulnerability::Findings。
Security Scan
Security::Scan 类的实例。安全扫描代表一个 Ci::Build,它输出一个已作为安全扫描结果输出的 Job Artifact,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,因为重命名大型表需要付出很大努力。
Identifier
Vulnerabilities::Identifier 类的实例。每个漏洞都会被赋予一个唯一标识符,该标识符可以从其发现中派生,从而使同一 Vulnerability 的多个发现能够相应地关联起来。
Vulnerability Read
Vulnerabilities::Read 类的实例。这是 Vulnerability 和 Vulnerability::Finding 数据的非规范化记录,用于提高向前端过滤查询漏洞数据的性能。
Remediation
Vulnerabilities::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来自动撤销检测到的任何泄露的密钥。
此时我们只有 Security::Finding 记录,而不是 Vulnerability 记录,因为这些发现不在项目的默认分支中。
下面描述了一些这些 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的Feedback记录来记录当前状态。 - 如果它们尚不存在,则创建一个
Vulnerability Finding和一个带有present_on_default_branch: false属性的Vulnerability,并关联一个反映状态变更的State Transition。
您可以选择为状态变更添加注释,该注释会记录在 Feedback 和 State Transition 上。
问题或合并请求创建
如果您选择"创建问题"或"创建合并请求",当前会发生以下情况:
- 创建一个
Vulnerabilities::Feedback记录。该 Feedback 将具有issue或merge request的feedback_type,以及相应的非NULL的issue_id或merge_request_id。 - 如果它们尚不存在,则创建一个
Vulnerability Finding和一个带有present_on_default_branch: false属性的Vulnerability,并关联一个与所执行操作相应的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::Read 记录通过 PostgreSQL 数据库触发器在创建 Vulnerability::Finding 记录时创建,因此它们是我们摄入过程的一部分,尽管它们除了在报告页面上提供非规范化性能优势外,对过程没有影响。
这种创建方式本应是快速和无缝的,但已被证明难以调试和维护,并且可能会稍后迁移到应用层。
不再检测
如果 Vulnerability 记录具有 resolved_on_default_branch: true,漏洞报告上的"不再检测"徽章就会显示。
当管道在默认分支上运行时,由 Security::Ingestion::MarkAsResolvedService 设置此属性。具有 resolved_on_default_branch: false 且_不在_管道扫描结果中的漏洞被标记为已解决。
密钥检测和手动添加的漏洞被排除在此过程之外。