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.

derived gcp emits CanWriteData

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 typeIdentity
target typeData
source<principal>
target<Firestore Database / NoSQLDatabase node>
permissionsdatastore.entities.create
conditionsiam_permission resource_policy
state logicCONDITIONAL(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.'
move · open · esc close