gcp-firestore-inject-data
datastore.entities.create alone enables document injection (creation of new documents); without entities.update, the attacker cannot modify existing data but can poison via new entries.
match (effective permission)
{
"action": "datastore.entities.create",
"resource_type": "google.firestore.Database"
}
where
?principal DOES NOT have EFFECTIVE datastore.entities.update at the database scope
emit
| source type | Identity |
|---|---|
| target type | Data |
| source | <principal> |
| target | <Firestore Database / NoSQLDatabase node> |
| permissions | datastore.entities.create |
| conditions | iam_permission resource_policy |
| state logic | CONDITIONAL(iam_permission) when datastore.entities.create is confirmed effective but entities.update is not (or is denied). Interpretation: the attacker can insert new documents (poison downstream processors) but cannot modify existing ones. This is a narrower capability than full CanWriteData but still constitutes write-plane access and risk of data injection. Escalation via CanWriteData(CONDITIONAL) requires the downstream processor (Cloud Function, workflow) to consume the injected documents without validation. |
Narrative
{principal.name} holds datastore.entities.create on {database.name} and can inject new documents into the Firestore database. Without entities.update, the attacker cannot modify existing documents but can add new entries designed to poison downstream data processors.
Raw rule rules/derived/gcp/firestore.yaml
id: gcp-firestore-inject-data
emits: CanWriteData
description: datastore.entities.create alone enables document injection (creation of new documents); without
entities.update, the attacker cannot modify existing data but can poison via new entries.
match_effective_permission:
action: datastore.entities.create
resource_type: google.firestore.Database
where:
- ?principal DOES NOT have EFFECTIVE datastore.entities.update at the database scope
emit:
source_type: Identity
target_type: Data
source: <principal>
target: <Firestore Database / NoSQLDatabase node>
permissions:
- datastore.entities.create
conditions:
- iam_permission
- resource_policy
state_logic: 'CONDITIONAL(iam_permission) when datastore.entities.create is confirmed effective but
entities.update is not (or is denied). Interpretation: the attacker can insert new documents (poison
downstream processors) but cannot modify existing ones. This is a narrower capability than full CanWriteData
but still constitutes write-plane access and risk of data injection. Escalation via CanWriteData(CONDITIONAL)
requires the downstream processor (Cloud Function, workflow) to consume the injected documents without
validation.'
confidence: min(contributing_confidences) * 0.90
derived_from:
- datastore.entities.create effective permission (without entities.update) on Firestore Database
false_positive_note: "Document insertion (create-only) does NOT grant modification of existing documents.\
\ Applications that validate new document shape/content before processing may not be vulnerable to\
\ injection via creation alone. However, applications that trust the database as a source-of-truth\
\ and fail to re-validate on read ARE vulnerable. Flag with CONDITIONAL state to indicate the narrower\
\ risk. Escalation still depends on a downstream trigger (Cloud Function) that processes new documents\
\ \u2014 model separately in gcf.yaml / eventarc.yaml."
narrative: '{principal.name} holds datastore.entities.create on {database.name} and can inject new documents
into the Firestore database. Without entities.update, the attacker cannot modify existing documents
but can add new entries designed to poison downstream data processors.'