gcp-ar-remote-repo-upstream
match (record)
{
"field": "remoteRepositoryConfig",
"resource_type": "google.artifactregistry.Repository"
}
where
repository.mode == REMOTE
remoteRepositoryConfig.upstreamUri is set (public upstream registry URL)
emit
| source type | ArtifactRepository |
|---|---|
| target type | * |
| source | <remote Artifact Registry repository node> |
| target | <upstream registry / external ArtifactRepository node (or URL record)> |
Narrative
Repository {repo.name} is a REMOTE (proxy) repository caching artifacts from upstream {upstream_uri}; if the upstream is a public registry and the package namespace is not reserved, an attacker can publish a higher-version package there (dependency confusion) to poison builds that fetch via {repo.name}.
Raw rule rules/explicit/gcp-artifactregistry.yaml
id: gcp-ar-remote-repo-upstream
emits: ContainsResourceReference
applies_to:
- gcp
match_record:
resource_type: google.artifactregistry.Repository
field: remoteRepositoryConfig
where:
- repository.mode == REMOTE
- remoteRepositoryConfig.upstreamUri is set (public upstream registry URL)
emit:
source_type: ArtifactRepository
target_type: '*'
source: <remote Artifact Registry repository node>
target: <upstream registry / external ArtifactRepository node (or URL record)>
api_source: artifactregistry.projects.locations.repositories.get
evidence_field: remoteRepositoryConfig.upstreamUri
properties:
reference_kind: proxies_upstream
upstream_uri: <upstream registry URL>
is_public: <true if upstream is a public registry>
narrative: Repository {repo.name} is a REMOTE (proxy) repository caching artifacts from upstream {upstream_uri};
if the upstream is a public registry and the package namespace is not reserved, an attacker can publish
a higher-version package there (dependency confusion) to poison builds that fetch via {repo.name}.