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