gcp-gcf-public-invoke
match (record)
{
"field": "iamPolicy.bindings",
"resource_type": "google.cloudfunctions.Function"
}
where
?function.environment == GEN_1 (1st-gen function)
a binding on the FUNCTION's own iamPolicy grants roles/cloudfunctions.invoker to allUsers or allAuthenticatedUsers
ingressSettings is not ALLOW_INTERNAL_ONLY
emit
| target type | AnonymousIdentity |
|---|---|
| source | <function> |
| target | <AnonymousIdentity> |
| conditions | network_reachability |
Narrative
{function.name} (1st gen) is invocable from the internet (allUsers/allAuthenticatedUsers has roles/cloudfunctions.invoker, ingress not internal-only).
Raw rule rules/derived/gcp/gcf.yaml
id: gcp-gcf-public-invoke
emits: ExposedToInternet
match_record:
resource_type: google.cloudfunctions.Function
field: iamPolicy.bindings
where:
- ?function.environment == GEN_1 (1st-gen function)
- a binding on the FUNCTION's own iamPolicy grants roles/cloudfunctions.invoker to allUsers or allAuthenticatedUsers
- ingressSettings is not ALLOW_INTERNAL_ONLY
emit:
target_type: AnonymousIdentity
source: <function>
target: <AnonymousIdentity>
permissions: []
conditions:
- network_reachability
false_positive_note: 1st-gen ONLY. Enforcement point for 1st-gen is roles/cloudfunctions.invoker on
the function resource's own IAM policy. IAM-gated HTTP functions are NOT public. Requires allUsers/allAuthenticatedUsers
invoker AND non-internal ingress. allAuthenticatedUsers = any Google account, still broadly abusable.
narrative: '{function.name} (1st gen) is invocable from the internet (allUsers/allAuthenticatedUsers
has roles/cloudfunctions.invoker, ingress not internal-only).'