Avoid deep merging jobs for pipeline execution policies
CI configured in a pipeline execution policy will be merged with the project CI before a pipeline runs. The current merging strategy performs a deep merge, which means that attributes can be injected in a job from the project CI.
Steps to reproduce
- Create a group
- Go to Settings -> General
- Toggle the Permissions and group features section
- Enable Run customized CI YAML file as security policy actions
- Create a project
- Add a
.gitlab-ci.yml
file containing a variable:build job: stage: build script: - echo "Project CI" before_script: - echo "Injected from project CI"
- Go to Secure -> Policies
- Select New policy
- Select Scan execution policy
- Switch to .yaml mode and paste the following policy:
type: scan_execution_policy name: Compliance description: '' enabled: true rules: - type: pipeline branch_type: all actions: - scan: custom ci_configuration: |- build job: stage: build script: - echo "Security policy CI"
- Select Configure with a merge request and merge the MR
- On the project page, Select Build -> Pipelines
- Select Run pipeline
- Inspect the build job logs. The before scripts prints "Injected from project CI" even though it should be overwritten by the scan execution policy.
Implementation plan
We can remove the deep merge that was introduced in !136912 (merged):
diff --git a/ee/lib/gitlab/ci/config/security_orchestration_policies/processor.rb b/ee/lib/gitlab/ci/config/security_orchestration_policies/processor.rb
index 4ef52b5681b4..346c5e8d963a 100644
--- a/ee/lib/gitlab/ci/config/security_orchestration_policies/processor.rb
+++ b/ee/lib/gitlab/ci/config/security_orchestration_policies/processor.rb
@@ -31,7 +31,7 @@ def perform
if custom_scan_actions_enabled? && active_scan_custom_actions.any?
stages = merged_config.fetch(:stages, [])
- merged_config = merged_config.deep_merge(scan_custom_actions[:pipeline_scan])
+ merged_config = merged_config.merge(scan_custom_actions[:pipeline_scan])
# The stages array will not be merged by `deep_merge` so it has to be merged seperately.
merged_config[:stages] = stages + merged_config[:stages]
In addition to this, this will be fixed by Use security policy job name index pattern for ... (#432046 - closed). If jobs get unique names, there is no risk of them getting merged together.
Edited by Andy Schoenen