gcp-bigquery-explicit-can-modify-policy-row-access
bigquery.rowAccessPolicies.update or .delete lets a principal delete or broaden row-level security policies, gaining full-table access for themselves or others.
match (effective permission)
{
"action": [
"bigquery.rowAccessPolicies.update",
"bigquery.rowAccessPolicies.delete"
],
"resource_type": "google.bigquery.Dataset"
}
emit
| source type | Identity |
|---|---|
| target type | * |
| source | <principal> |
| target | <Dataset / Table row access policy node> |
| permissions | bigquery.rowAccessPolicies.update bigquery.rowAccessPolicies.delete |
| conditions | iam_permission |
| state logic | ACTIVE when bigquery.rowAccessPolicies.update OR bigquery.rowAccessPolicies.delete is confirmed effective; CONDITIONAL(iam_permission) when the effective permission is uncertain. |
Narrative
{principal.name} can modify or delete row-level access policies on {dataset.name} tables (bigquery.rowAccessPolicies.update or .delete), removing row-level filters and potentially exposing all rows to principals with getData.
Raw rule rules/explicit/gcp/bigquery.yaml
id: gcp-bigquery-explicit-can-modify-policy-row-access
emits: CanModifyPolicy
description: bigquery.rowAccessPolicies.update or .delete lets a principal delete or broaden row-level
security policies, gaining full-table access for themselves or others.
match_effective_permission:
action:
- bigquery.rowAccessPolicies.update
- bigquery.rowAccessPolicies.delete
resource_type: google.bigquery.Dataset
emit:
source_type: Identity
target_type: '*'
source: <principal>
target: <Dataset / Table row access policy node>
permissions:
- bigquery.rowAccessPolicies.update
- bigquery.rowAccessPolicies.delete
conditions:
- iam_permission
state_logic: ACTIVE when bigquery.rowAccessPolicies.update OR bigquery.rowAccessPolicies.delete is confirmed
effective; CONDITIONAL(iam_permission) when the effective permission is uncertain.
false_positive_note: "Row-level security in BigQuery is implemented as RowAccessPolicy resources that\
\ filter rows returned to a querying principal. bigquery.rowAccessPolicies.update allows modifying\
\ these filters; bigquery.rowAccessPolicies.delete allows deleting them entirely, both achieving row-policy\
\ bypass. The attacker's actual ability to read the formerly-restricted rows then depends on their\
\ also holding bigquery.tables.getData (the CanReadData condition). Only emit CanModifyPolicy; do\
\ not emit CanReadData directly from this rule \u2014 the existing CanReadData rule (gcp-bigquery-read-data)\
\ handles the data-access gate. Both permissions are present in roles/bigquery.admin and roles/bigquery.dataOwner."
narrative: '{principal.name} can modify or delete row-level access policies on {dataset.name} tables
(bigquery.rowAccessPolicies.update or .delete), removing row-level filters and potentially exposing
all rows to principals with getData.'
derived_from:
- bigquery.rowAccessPolicies.update or .delete effective permission
api_source: Cloud Asset Inventory analyzeIamPolicy
evidence_field: bigquery.rowAccessPolicies update/delete effective permission