Back
Id3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b
RulenameGCP Audit Logs - Storage Bucket Made Public
DescriptionDetects when a Google Cloud Storage bucket is made publicly accessible by granting permissions to allUsers or allAuthenticatedUsers.

Making buckets public can expose sensitive data to unauthorized access and may indicate a misconfiguration or malicious activity.

Adversaries may make buckets public to exfiltrate data or as part of a data exposure attack.

This rule monitors setIamPermissions operations that add public access roles to storage buckets.
SeverityHigh
TacticsCollection
InitialAccess
Exfiltration
TechniquesT1530
T1078.004
T1567.002
Required data connectorsGCPAuditLogsDefinition
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPStorageBucketMadePublic.yaml
Version1.0.0
Arm template3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b.json
Deploy To Azure
GCPAuditLogs
| where ServiceName == "storage.googleapis.com"
| where MethodName == "storage.setIamPermissions"
| where GCPResourceType == "gcs_bucket"
| extend 
    ServiceDataJson = parse_json(ServiceData),
    RequestMetadataJson = parse_json(RequestMetadata),
    AuthInfoJson = parse_json(AuthenticationInfo),
    AuthzInfoJson = parse_json(AuthorizationInfo)
| extend PolicyDelta = ServiceDataJson.policyDelta.bindingDeltas
| mv-expand PolicyDelta
| extend 
    Action = tostring(PolicyDelta.action),
    Member = tostring(PolicyDelta.member),
    Role = tostring(PolicyDelta.role)
| where Action == "ADD"
| where Member in~ ("allUsers", "allAuthenticatedUsers")
| extend 
    BucketName = extract(@"buckets/([^/]+)", 1, GCPResourceName),
    CallerIpAddress = tostring(RequestMetadataJson.callerIp),
    UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),
    AuthEmail = tostring(AuthInfoJson.principalEmail),
    Permission = tostring(AuthzInfoJson[0].permission),
    PermissionGranted = tostring(AuthzInfoJson[0].granted)
| extend 
    PublicAccessType = case(
        Member =~ "allUsers", "Public to Everyone",
        Member =~ "allAuthenticatedUsers", "Public to All Authenticated Users",
        "Unknown"),
    AccountName = tostring(split(PrincipalEmail, "@")[0]), 
    AccountUPNSuffix = tostring(split(PrincipalEmail, "@")[1])
| project TimeGenerated,
          PrincipalEmail,
          AuthEmail,
          ProjectId,
          BucketName,
          ResourceName = GCPResourceName,
          PublicAccessType,
          Member,
          Role,
          CallerIpAddress,
          UserAgent,
          MethodName,
          ServiceName,
          Severity,
          Permission,
          PermissionGranted,
          LogName,
          InsertId,
          AccountName,
          AccountUPNSuffix
queryFrequency: 1h
entityMappings:
- fieldMappings:
  - columnName: PrincipalEmail
    identifier: FullName
  - columnName: AccountName
    identifier: Name
  - columnName: AccountUPNSuffix
    identifier: UPNSuffix
  entityType: Account
- fieldMappings:
  - columnName: CallerIpAddress
    identifier: Address
  entityType: IP
- fieldMappings:
  - columnName: ProjectId
    identifier: Name
  - columnName: ResourceName
    identifier: InstanceName
  entityType: CloudApplication
triggerThreshold: 0
triggerOperator: gt
severity: High
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPStorageBucketMadePublic.yaml
alertDetailsOverride:
  alertDisplayNameFormat: GCP Storage Bucket {{BucketName}} Made Public by {{PrincipalEmail}}
  alertDescriptionFormat: |-
    User {{PrincipalEmail}} made storage bucket {{BucketName}} publicly accessible in project {{ProjectId}}.
    This may expose sensitive data to unauthorized access. Investigate immediately to determine if this action was authorized and assess potential data exposure.
    Review bucket contents and access logs for any unauthorized access attempts.
query: |
  GCPAuditLogs
  | where ServiceName == "storage.googleapis.com"
  | where MethodName == "storage.setIamPermissions"
  | where GCPResourceType == "gcs_bucket"
  | extend 
      ServiceDataJson = parse_json(ServiceData),
      RequestMetadataJson = parse_json(RequestMetadata),
      AuthInfoJson = parse_json(AuthenticationInfo),
      AuthzInfoJson = parse_json(AuthorizationInfo)
  | extend PolicyDelta = ServiceDataJson.policyDelta.bindingDeltas
  | mv-expand PolicyDelta
  | extend 
      Action = tostring(PolicyDelta.action),
      Member = tostring(PolicyDelta.member),
      Role = tostring(PolicyDelta.role)
  | where Action == "ADD"
  | where Member in~ ("allUsers", "allAuthenticatedUsers")
  | extend 
      BucketName = extract(@"buckets/([^/]+)", 1, GCPResourceName),
      CallerIpAddress = tostring(RequestMetadataJson.callerIp),
      UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),
      AuthEmail = tostring(AuthInfoJson.principalEmail),
      Permission = tostring(AuthzInfoJson[0].permission),
      PermissionGranted = tostring(AuthzInfoJson[0].granted)
  | extend 
      PublicAccessType = case(
          Member =~ "allUsers", "Public to Everyone",
          Member =~ "allAuthenticatedUsers", "Public to All Authenticated Users",
          "Unknown"),
      AccountName = tostring(split(PrincipalEmail, "@")[0]), 
      AccountUPNSuffix = tostring(split(PrincipalEmail, "@")[1])
  | project TimeGenerated,
            PrincipalEmail,
            AuthEmail,
            ProjectId,
            BucketName,
            ResourceName = GCPResourceName,
            PublicAccessType,
            Member,
            Role,
            CallerIpAddress,
            UserAgent,
            MethodName,
            ServiceName,
            Severity,
            Permission,
            PermissionGranted,
            LogName,
            InsertId,
            AccountName,
            AccountUPNSuffix
tactics:
- Collection
- InitialAccess
- Exfiltration
queryPeriod: 1h
customDetails:
  ProjectId: ProjectId
  PublicAccessType: PublicAccessType
  RoleGranted: Role
  BucketName: BucketName
  UserAgent: UserAgent
  Permission: Permission
  ResourceName: ResourceName
relevantTechniques:
- T1530
- T1078.004
- T1567.002
requiredDataConnectors:
- connectorId: GCPAuditLogsDefinition
  dataTypes:
  - GCPAuditLogs
id: 3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b
kind: Scheduled
version: 1.0.0
description: |
  'Detects when a Google Cloud Storage bucket is made publicly accessible by granting permissions to allUsers or allAuthenticatedUsers.
  Making buckets public can expose sensitive data to unauthorized access and may indicate a misconfiguration or malicious activity.
  Adversaries may make buckets public to exfiltrate data or as part of a data exposure attack.
  This rule monitors setIamPermissions operations that add public access roles to storage buckets.'
status: Available
name: GCP Audit Logs - Storage Bucket Made Public
tags:
- GCP
- Storage
- Data Exposure
- Cloud Security
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "User {{PrincipalEmail}} made storage bucket {{BucketName}} publicly accessible in project {{ProjectId}}.\nThis may expose sensitive data to unauthorized access. Investigate immediately to determine if this action was authorized and assess potential data exposure.\nReview bucket contents and access logs for any unauthorized access attempts.",
          "alertDisplayNameFormat": "GCP Storage Bucket {{BucketName}} Made Public by {{PrincipalEmail}}"
        },
        "alertRuleTemplateName": "3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b",
        "customDetails": {
          "BucketName": "BucketName",
          "Permission": "Permission",
          "ProjectId": "ProjectId",
          "PublicAccessType": "PublicAccessType",
          "ResourceName": "ResourceName",
          "RoleGranted": "Role",
          "UserAgent": "UserAgent"
        },
        "description": "'Detects when a Google Cloud Storage bucket is made publicly accessible by granting permissions to allUsers or allAuthenticatedUsers.\nMaking buckets public can expose sensitive data to unauthorized access and may indicate a misconfiguration or malicious activity.\nAdversaries may make buckets public to exfiltrate data or as part of a data exposure attack.\nThis rule monitors setIamPermissions operations that add public access roles to storage buckets.'\n",
        "displayName": "GCP Audit Logs - Storage Bucket Made Public",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "PrincipalEmail",
                "identifier": "FullName"
              },
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "CallerIpAddress",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "CloudApplication",
            "fieldMappings": [
              {
                "columnName": "ProjectId",
                "identifier": "Name"
              },
              {
                "columnName": "ResourceName",
                "identifier": "InstanceName"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPStorageBucketMadePublic.yaml",
        "query": "GCPAuditLogs\n| where ServiceName == \"storage.googleapis.com\"\n| where MethodName == \"storage.setIamPermissions\"\n| where GCPResourceType == \"gcs_bucket\"\n| extend \n    ServiceDataJson = parse_json(ServiceData),\n    RequestMetadataJson = parse_json(RequestMetadata),\n    AuthInfoJson = parse_json(AuthenticationInfo),\n    AuthzInfoJson = parse_json(AuthorizationInfo)\n| extend PolicyDelta = ServiceDataJson.policyDelta.bindingDeltas\n| mv-expand PolicyDelta\n| extend \n    Action = tostring(PolicyDelta.action),\n    Member = tostring(PolicyDelta.member),\n    Role = tostring(PolicyDelta.role)\n| where Action == \"ADD\"\n| where Member in~ (\"allUsers\", \"allAuthenticatedUsers\")\n| extend \n    BucketName = extract(@\"buckets/([^/]+)\", 1, GCPResourceName),\n    CallerIpAddress = tostring(RequestMetadataJson.callerIp),\n    UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),\n    AuthEmail = tostring(AuthInfoJson.principalEmail),\n    Permission = tostring(AuthzInfoJson[0].permission),\n    PermissionGranted = tostring(AuthzInfoJson[0].granted)\n| extend \n    PublicAccessType = case(\n        Member =~ \"allUsers\", \"Public to Everyone\",\n        Member =~ \"allAuthenticatedUsers\", \"Public to All Authenticated Users\",\n        \"Unknown\"),\n    AccountName = tostring(split(PrincipalEmail, \"@\")[0]), \n    AccountUPNSuffix = tostring(split(PrincipalEmail, \"@\")[1])\n| project TimeGenerated,\n          PrincipalEmail,\n          AuthEmail,\n          ProjectId,\n          BucketName,\n          ResourceName = GCPResourceName,\n          PublicAccessType,\n          Member,\n          Role,\n          CallerIpAddress,\n          UserAgent,\n          MethodName,\n          ServiceName,\n          Severity,\n          Permission,\n          PermissionGranted,\n          LogName,\n          InsertId,\n          AccountName,\n          AccountUPNSuffix\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT1H",
        "severity": "High",
        "status": "Available",
        "subTechniques": [
          "T1078.004",
          "T1567.002"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Collection",
          "Exfiltration",
          "InitialAccess"
        ],
        "tags": [
          "GCP",
          "Storage",
          "Data Exposure",
          "Cloud Security"
        ],
        "techniques": [
          "T1078",
          "T1530",
          "T1567"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}