gcp-deploy-gcs-bucket-write-modifies-code
Write access to the Cloud Deploy pipeline's GCS source bucket allows injecting malicious skaffold.yaml into every render job.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
?gcs_bucket is the Skaffold source
ObjectStorage bucket for a Cloud Deploy delivery pipeline
?gcs_bucket.name matches gs://PROJECT-clouddeploy-pipeline-REGION/ or the pipeline's configured source bucket
?principal has effective storage.objects.create on ?gcs_bucket
emit
| source type | Identity |
|---|---|
| target type | BuildWorker |
| source | ?principal |
| target | <render-phase Cloud Build worker (BuildWorker) for all releases from this pipeline> |
| permissions | storage.objects.create |
| conditions | iam_permission |
| state logic | ACTIVE when ?principal holds effective storage.objects.create on the pipeline's GCS source bucket. The write is realized immediately upon release creation. BLOCKED when an IAM deny policy denies storage.objects.create on the bucket. |
Narrative
{principal.name} can write to the Cloud Deploy pipeline's Skaffold source GCS bucket (storage.objects.create), allowing injection of a malicious skaffold.yaml that executes in the render Cloud Build worker as the pipeline's render SA. Every release created from this bucket will execute the attacker-injected hooks/manifests. Cite cicd-chains cicd-modify-buildspec-executes-as to collapse into CanExecuteAs.
Raw rule rules/derived/gcp/clouddeploy.yaml
id: gcp-deploy-gcs-bucket-write-modifies-code
emits: CanModifyCode
description: Write access to the Cloud Deploy pipeline's GCS source bucket allows injecting malicious
skaffold.yaml into every render job.
applies_to:
- gcp
match:
- - principal: null
- CanWrite
- gcs_bucket: null
where:
- ?gcs_bucket is the Skaffold source ObjectStorage bucket for a Cloud Deploy delivery pipeline
- ?gcs_bucket.name matches gs://PROJECT-clouddeploy-pipeline-REGION/ or the pipeline's configured source
bucket
- ?principal has effective storage.objects.create on ?gcs_bucket
emit:
source_type: Identity
target_type: BuildWorker
source: ?principal
target: <render-phase Cloud Build worker (BuildWorker) for all releases from this pipeline>
permissions:
- storage.objects.create
conditions:
- iam_permission
state_logic: ACTIVE when ?principal holds effective storage.objects.create on the pipeline's GCS source
bucket. The write is realized immediately upon release creation. BLOCKED when an IAM deny policy denies
storage.objects.create on the bucket.
confidence: 0.94
derived_from:
- ?principal CanWrite ?gcs_bucket (GCP IAM storage permission)
- pipeline source bucket configuration
false_positive_note: "Verify that ?gcs_bucket is the pipeline's configured source bucket (query the\
\ pipeline's deliveryPipelineYamlFile field or similar). A principal with storage.objects.create on\
\ the project's temporary/artifact buckets is NOT a threat to this pipeline unless those buckets are\
\ the configured source. The injected skaffold.yaml runs in the render-phase BuildWorker as the render\
\ SA. Cite cicd-chains cicd-modify-buildspec-executes-as to collapse CanModifyCode + ExecutesAs into\
\ CanExecuteAs(principal \u2192 render_sa)."
narrative: '{principal.name} can write to the Cloud Deploy pipeline''s Skaffold source GCS bucket (storage.objects.create),
allowing injection of a malicious skaffold.yaml that executes in the render Cloud Build worker as
the pipeline''s render SA. Every release created from this bucket will execute the attacker-injected
hooks/manifests. Cite cicd-chains cicd-modify-buildspec-executes-as to collapse into CanExecuteAs.'