Vulnerabilities from child pipelines aren't correctly compared in MR security widget
Summary
When security scans are run within a child pipeline triggered from a default branch's pipeline, the vulnerabilities they discover are incorporated into the security dashboard, but the results aren't correctly compared with future MRs in the project.
Steps to reproduce
Include a security scanner as a downstream child pipeline in your default branch pipeline:
security-scans:
stage: test
trigger:
include:
- template: Security/SAST.gitlab-ci.yml
strategy: depend
Example Project
@lstahlman to link
What is the current bug behavior?
Security scans complete successfully, and the findings captured do make it back to the security dashboard, but are not compared correctly in the context of the MR widget.
This means that previously-addressed vulnerabilities already present in a project's security dashboard will be presented as new in merge requests, demanding approval (if configured) and creating noise.
What is the expected correct behavior?
Vulnerabilities should only be presented as new once.
Relevant logs and/or screenshots
Output of checks
Possible fixes
Change the Ci::Pipeline#security_reports
method to account for artifacts generated by the child pipelines. It can be beneficial to put this new logic behind a feature flag so we can turn this behavior off if we find an issue with it.
Also, please consider updating the existing docs.
Note: With this change the child pipelines for the default branch will be fully supported but the MR pipelines won't be. See this thread for more information.
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 7a606c0b417a..0ccd3bbf3461 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -1373,7 +1373,7 @@ def security_reports(report_types: [])
types_to_collect = report_types.empty? ? ::Ci::JobArtifact::SECURITY_REPORT_FILE_TYPES : report_types
::Gitlab::Ci::Reports::Security::Reports.new(self).tap do |security_reports|
- latest_report_builds(reports_scope).each do |build|
+ latest_report_builds_in_self_and_project_descendants(reports_scope).each do |build|
build.collect_security_reports!(security_reports, report_types: types_to_collect)
end
end