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
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"
}
]
}