gcp-gcr-public-pull

artifacts bucket ACL grants allUsers storage.objects.get - GCR registry is publicly pullable without authentication, exposing embedded secrets and proprietary code.

derived gcp emits ExposedToInternet

match (effective permission)

{ "action": "storage.objects.get", "resource_type": "storage.googleapis.com/Bucket" }

where

resource.name matches 'artifacts.<PROJECT>.appspot.com' (the GCR artifacts backing bucket, not an arbitrary GCS bucket) binding.member in ['allUsers', 'allAuthenticatedUsers'] (the effective permission storage.objects.get is granted to public principals on the artifacts bucket via a binding in the bucket IAM policy)

emit

source typeContainerRegistry
target typeAnonymousIdentity
source<ContainerRegistry node for gcr.io/PROJECT>
target<AnonymousIdentity>
permissionsstorage.objects.get
state logicACTIVE when the bucket IAM grants allUsers storage.objects.get (any internet user can pull). CONDITIONAL(resource_policy) when only allAuthenticatedUsers (any Google-authenticated user worldwide) have pull — a real misconfiguration but not anonymous public; emit with confidence: 0.8 and note the member scope. BLOCKED when Uniform Bucket-Level Access is enabled AND org policy constraints/storage.publicAccessPrevention is enforced at the bucket or project — GCS rejects public ACLs in that configuration.

Narrative

The GCR registry for project {project.name} is publicly pullable: the artifacts bucket grants {allUsers|allAuthenticatedUsers} storage.objects.get. Any internet user can pull container images and inspect their layers for embedded credentials, secrets, configuration, or proprietary code - no project credentials required.

Raw rule rules/derived/gcp/gcr.yaml

id: gcp-gcr-public-pull
emits: ExposedToInternet
description: "artifacts bucket ACL grants allUsers storage.objects.get \u2014 GCR registry is publicly\
  \ pullable without authentication, exposing embedded secrets and proprietary code."
match_effective_permission:
  action: storage.objects.get
  resource_type: storage.googleapis.com/Bucket
where:
- resource.name matches 'artifacts.<PROJECT>.appspot.com' (the GCR artifacts backing bucket, not an arbitrary
  GCS bucket)
- binding.member in ['allUsers', 'allAuthenticatedUsers'] (the effective permission storage.objects.get
  is granted to public principals on the artifacts bucket via a binding in the bucket IAM policy)
emit:
  source_type: ContainerRegistry
  target_type: AnonymousIdentity
  source: <ContainerRegistry node for gcr.io/PROJECT>
  target: <AnonymousIdentity>
  permissions:
  - storage.objects.get
  conditions: []
  state_logic: "ACTIVE when the bucket IAM grants allUsers storage.objects.get (any internet user can\
    \ pull). CONDITIONAL(resource_policy) when only allAuthenticatedUsers (any Google-authenticated user\
    \ worldwide) have pull \u2014 a real misconfiguration but not anonymous public; emit with confidence:\
    \ 0.8 and note the member scope. BLOCKED when Uniform Bucket-Level Access is enabled AND org policy\
    \ constraints/storage.publicAccessPrevention is enforced at the bucket or project \u2014 GCS rejects\
    \ public ACLs in that configuration."
  confidence: 0.9
  derived_from:
  - allUsers or allAuthenticatedUsers storage.objects.get on artifacts.<PROJECT>.appspot.com (from storage.buckets.getIamPolicy)
  false_positive_note: "allUsers vs allAuthenticatedUsers is a material distinction: allUsers = truly\
    \ anonymous pull (confidence 0.9); allAuthenticatedUsers = any Google account worldwide (confidence\
    \ 0.8, note in analyst narrative). Neither equals project/org members only. constraints/storage.publicAccessPrevention\
    \ at bucket or project level blocks this ACL from being set \u2014 if the constraint is enforced,\
    \ this rule should not fire (the bucket cannot have public ACLs). Verify the constraint status before\
    \ emitting ACTIVE."
  narrative: "The GCR registry for project {project.name} is publicly pullable: the artifacts bucket grants\
    \ {allUsers|allAuthenticatedUsers} storage.objects.get. Any internet user can pull container images\
    \ and inspect their layers for embedded credentials, secrets, configuration, or proprietary code \u2014\
    \ no project credentials required."
move · open · esc close