Detection rules › Splunk

Detect New Open GCP Storage Buckets

Status
experimental
Severity
medium
Author
Shannon Davis, Splunk
Source
github.com/splunk/security_content

The following analytic identifies the creation of new open/public GCP Storage buckets. It leverages GCP PubSub events, specifically monitoring for the storage.setIamPermissions method and checks if the allUsers member is added. This activity is significant because open storage buckets can expose sensitive data to the public, posing a severe security risk. If confirmed malicious, an attacker could access, modify, or delete data within the bucket, leading to data breaches and potential compliance violations.

Known false positives

  • While this search has no known false positives, it is possible that a GCP admin has legitimately created a public bucket for a specific purpose. That said, GCP strongly advises against granting full control to the "allUsers" group.

MITRE ATT&CK coverage

TacticTechniques
Collection

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule body

name: Detect New Open GCP Storage Buckets
id: f6ea3466-d6bb-11ea-87d0-0242ac130003
version: 8
creation_date: '2020-08-19'
modification_date: '2026-05-13'
author: Shannon Davis, Splunk
status: experimental
type: TTP
description: The following analytic identifies the creation of new open/public GCP Storage buckets. It leverages GCP PubSub events, specifically monitoring for the `storage.setIamPermissions` method and checks if the `allUsers` member is added. This activity is significant because open storage buckets can expose sensitive data to the public, posing a severe security risk. If confirmed malicious, an attacker could access, modify, or delete data within the bucket, leading to data breaches and potential compliance violations.
data_source: []
search: |-
    `google_gcp_pubsub_message` data.resource.type=gcs_bucket data.protoPayload.methodName=storage.setIamPermissions
      | spath output=action path=data.protoPayload.serviceData.policyDelta.bindingDeltas{}.action
      | spath output=user path=data.protoPayload.authenticationInfo.principalEmail
      | spath output=location path=data.protoPayload.resourceLocation.currentLocations{}
      | spath output=src path=data.protoPayload.requestMetadata.callerIp
      | spath output=bucketName path=data.protoPayload.resourceName
      | spath output=role path=data.protoPayload.serviceData.policyDelta.bindingDeltas{}.role
      | spath output=member path=data.protoPayload.serviceData.policyDelta.bindingDeltas{}.member
      | search (member=allUsers AND action=ADD)
      | table  _time, bucketName, src, user, location, action, role, member
      | search `detect_new_open_gcp_storage_buckets_filter`
how_to_implement: This search relies on the Splunk Add-on for Google Cloud Platform, setting up a Cloud Pub/Sub input, along with the relevant GCP PubSub topics and logging sink to capture GCP Storage Bucket events (https://cloud.google.com/logging/docs/routing/overview).
known_false_positives: While this search has no known false positives, it is possible that a GCP admin has legitimately created a public bucket for a specific purpose. That said, GCP strongly advises against granting full control to the "allUsers" group.
references: []
finding:
    title: |
        "allUser" member added to $bucketName$ by $user$ making the bucket available to the public
    entity:
        field: user
        type: user
        score: 50
analytic_story:
    - Suspicious GCP Storage Activities
asset_type: GCP Storage Bucket
mitre_attack_id:
    - T1530
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: cloud
security_domain: network

Stages and Predicates

Stage 1: search

`google_gcp_pubsub_message` data.resource.type=gcs_bucket data.protoPayload.methodName=storage.setIamPermissions

Stage 2: spath

| spath output=action path=data.protoPayload.serviceData.policyDelta.bindingDeltas{}.action

Stage 3: spath

| spath output=user path=data.protoPayload.authenticationInfo.principalEmail

Stage 4: spath

| spath output=location path=data.protoPayload.resourceLocation.currentLocations{}

Stage 5: spath

| spath output=src path=data.protoPayload.requestMetadata.callerIp

Stage 6: spath

| spath output=bucketName path=data.protoPayload.resourceName

Stage 7: spath

| spath output=role path=data.protoPayload.serviceData.policyDelta.bindingDeltas{}.role

Stage 8: spath

| spath output=member path=data.protoPayload.serviceData.policyDelta.bindingDeltas{}.member

Stage 9: search

| search (member=allUsers AND action=ADD)

Stage 10: table

| table  _time, bucketName, src, user, location, action, role, member

Stage 11: search

| search `detect_new_open_gcp_storage_buckets_filter`

Indicators

These rows show field, operator, and value matches.