gcp-bigquery-explicit-can-modify-code-remote-function
bigquery.routines.update on a REMOTE_FUNCTION Routine lets a principal change the Cloud Run endpoint the function invokes - effectively modifying the code/target at runtime.
match (effective permission)
{
"action": "bigquery.routines.update",
"resource_type": "google.bigquery.Routine"
}
where
Routine.routineType == 'REMOTE_FUNCTION' (not a UDF or standard routine)
Routine.remoteFunctionOptions.endpoint is set to a Cloud Run service or HTTPS URL
emit
| source type | Identity |
|---|---|
| target type | Messaging |
| source | <principal> |
| target | <BigQuery Routine (REMOTE_FUNCTION) node> |
| permissions | bigquery.routines.update |
| conditions | iam_permission |
| state logic | ACTIVE when bigquery.routines.update is confirmed on the Routine and the Routine is of type REMOTE_FUNCTION; CONDITIONAL(iam_permission) when the permission is inherited at project scope but may be scoped away. |
Narrative
{principal.name} can modify remote function {routine.name} (bigquery.routines.update), changing its Cloud Run endpoint to an attacker-controlled service. Any query calling this function will POST to the attacker's URL, enabling data exfiltration and lateral movement. The cicd-chains linchpin (cicd-modify-buildspec-executes-as) or can-execute-as linchpin captures downstream CanExecuteAs if the attacker's endpoint itself ExecutesAs a privileged identity.
Raw rule rules/explicit/gcp/bigquery.yaml
id: gcp-bigquery-explicit-can-modify-code-remote-function
emits: CanModifyCode
description: "bigquery.routines.update on a REMOTE_FUNCTION Routine lets a principal change the Cloud\
\ Run endpoint the function invokes \u2014 effectively modifying the code/target at runtime."
match_effective_permission:
action: bigquery.routines.update
resource_type: google.bigquery.Routine
where:
- Routine.routineType == 'REMOTE_FUNCTION' (not a UDF or standard routine)
- Routine.remoteFunctionOptions.endpoint is set to a Cloud Run service or HTTPS URL
emit:
source_type: Identity
target_type: Messaging
source: <principal>
target: <BigQuery Routine (REMOTE_FUNCTION) node>
permissions:
- bigquery.routines.update
conditions:
- iam_permission
state_logic: ACTIVE when bigquery.routines.update is confirmed on the Routine and the Routine is of
type REMOTE_FUNCTION; CONDITIONAL(iam_permission) when the permission is inherited at project scope
but may be scoped away.
false_positive_note: "bigquery.routines.update allows modifying the routine definition, including the\
\ remoteFunctionOptions.endpoint (the Cloud Run URL or HTTPS endpoint). By changing the endpoint to\
\ an attacker-controlled service, any query calling this remote function will invoke the attacker's\
\ code with the query's data. This is a cross-service lateral movement vector: if the remote function\
\ originally called a Cloud Run service (which ExecutesAs a SA), rerouting it to an attacker-controlled\
\ endpoint bypasses the original SA's trust and access controls. Note: updating a routine of type\
\ FUNCTION or TABLE_VALUED_FUNCTION (SQL UDFs) also modifies code but does not have external invoke\
\ implications \u2014 those are pure SQL UDF updates."
narrative: '{principal.name} can modify remote function {routine.name} (bigquery.routines.update), changing
its Cloud Run endpoint to an attacker-controlled service. Any query calling this function will POST
to the attacker''s URL, enabling data exfiltration and lateral movement. The cicd-chains linchpin
(cicd-modify-buildspec-executes-as) or can-execute-as linchpin captures downstream CanExecuteAs if
the attacker''s endpoint itself ExecutesAs a privileged identity.'
derived_from:
- bigquery.routines.update effective permission on google.bigquery.Routine (REMOTE_FUNCTION)
api_source: Cloud Asset Inventory analyzeIamPolicy
evidence_field: bigquery.routines.update effective permission