Analytic rule catalog
GCP Audit Logs - Storage Bucket Made Public
Back
| Id | 3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b |
| Rulename | GCP Audit Logs - Storage Bucket Made Public |
| 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 |
| Tactics | Collection InitialAccess Exfiltration |
| Techniques | T1530 T1078.004 T1567.002 |
| Required data connectors | GCPAuditLogsDefinition |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 1h |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPStorageBucketMadePublic.yaml |
| Version | 1.0.0 |
| Arm template | 3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b.json |
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"
}
]
}