GCP Audit Logs - Storage Bucket Made Public
| 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 Cloud Platform Audit Logs/Analytic Rules/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
relevantTechniques:
- T1530
- T1078.004
- T1567.002
version: 1.0.0
severity: High
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google Cloud Platform Audit Logs/Analytic Rules/GCPStorageBucketMadePublic.yaml
name: GCP Audit Logs - Storage Bucket Made Public
customDetails:
ProjectId: ProjectId
UserAgent: UserAgent
Permission: Permission
RoleGranted: Role
ResourceName: ResourceName
PublicAccessType: PublicAccessType
BucketName: BucketName
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.'
queryFrequency: 1h
tactics:
- Collection
- InitialAccess
- Exfiltration
triggerThreshold: 0
queryPeriod: 1h
id: 3a8d7f9e-4b2c-4e5d-8c6b-9f1a3d5e8c7b
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
requiredDataConnectors:
- connectorId: GCPAuditLogsDefinition
dataTypes:
- GCPAuditLogs
triggerOperator: gt
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.
tags:
- GCP
- Storage
- Data Exposure
- Cloud Security
status: Available
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
kind: Scheduled