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
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: PrincipalEmail
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: AccountUPNSuffix
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: CallerIpAddress
- entityType: CloudApplication
  fieldMappings:
  - identifier: Name
    columnName: ProjectId
  - identifier: InstanceName
    columnName: ResourceName
name: GCP Audit Logs - Storage Bucket Made Public
kind: Scheduled
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPStorageBucketMadePublic.yaml
triggerOperator: gt
status: Available
queryPeriod: 1h
requiredDataConnectors:
- connectorId: GCPAuditLogsDefinition
  dataTypes:
  - GCPAuditLogs
tactics:
- Collection
- InitialAccess
- Exfiltration
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
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.'
severity: High
tags:
- GCP
- Storage
- Data Exposure
- Cloud Security
id: 3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b
customDetails:
  ProjectId: ProjectId
  RoleGranted: Role
  ResourceName: ResourceName
  PublicAccessType: PublicAccessType
  Permission: Permission
  BucketName: BucketName
  UserAgent: UserAgent
triggerThreshold: 0
queryFrequency: 1h
alertDetailsOverride:
  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.
  alertDisplayNameFormat: GCP Storage Bucket {{BucketName}} Made Public by {{PrincipalEmail}}
version: 1.0.0
relevantTechniques:
- T1530
- T1078.004
- T1567.002
{
  "$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"
    }
  ]
}