AWS S3 Bucket Policy Added to Allow Public Access
Detects when an Amazon S3 bucket policy is modified to grant public access using a wildcard (Principal:"") statement. This rule analyzes PutBucketPolicy events that include both Effect=Allow and Principal:"" in the request parameters, indicating that permissions were extended to all identities, potentially making the bucket or its contents publicly accessible. Publicly exposing an S3 bucket is one of the most common causes of sensitive data leaks in AWS environments. Adversaries or misconfigurations can leverage this exposure to exfiltrate data, host malicious content, or collect credentials and logs left in open storage.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2025/10/30"
3integration = ["aws"]
4maturity = "production"
5updated_date = "2025/10/30"
6
7[rule]
8author = ["Elastic"]
9description = """
10Detects when an Amazon S3 bucket policy is modified to grant public access using a wildcard (Principal:"*") statement.
11This rule analyzes PutBucketPolicy events that include both Effect=Allow and Principal:"*" in the request parameters,
12indicating that permissions were extended to all identities, potentially making the bucket or its contents publicly
13accessible. Publicly exposing an S3 bucket is one of the most common causes of sensitive data leaks in AWS environments.
14Adversaries or misconfigurations can leverage this exposure to exfiltrate data, host malicious content, or collect
15credentials and logs left in open storage.
16"""
17event_category_override = "event.type"
18false_positives = [
19 """
20 This rule does not differentiate by itself whether the same policy also includes Deny statements that restrict
21 public access. If a policy includes both Effect=Allow and Effect=Deny with Principal:"*", this rule may still
22 trigger. Such cases should be manually analyzed to verify whether the Deny statement effectively negates the public
23 exposure.
24 """,
25]
26index = ["filebeat-*", "logs-aws.cloudtrail-*"]
27language = "eql"
28license = "Elastic License v2"
29name = "AWS S3 Bucket Policy Added to Allow Public Access"
30note = """## Triage and analysis
31
32> **Disclaimer**:
33> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance.
34> While every effort has been made to ensure its quality, we recommend validating the content and adapting it to your specific environment and operational needs.
35
36### Investigating AWS S3 Bucket Policy Added to Allow Public Access
37
38This rule detects modifications to Amazon S3 bucket policies using the `PutBucketPolicy` API where both `Effect=Allow`
39and `Principal:"*"` are present. This effectively grants permissions to all AWS identities, including unauthenticated users.
40Such exposure can result in sensitive data leaks, ransomware staging, or unauthorized data collection.
41
42This rule focuses on policy-based exposure rather than ACL-based or block-public-access configurations.
43It will still trigger if a bucket policy includes both `Effect=Allow` and `Effect=Deny` statements that contain `Principal:"*"`. Those cases should be reviewed to confirm whether the `Deny` statement restricts access sufficiently.
44
45#### Possible investigation steps
46
47- **Identify the Actor**
48 - Review `aws.cloudtrail.user_identity.arn`, `aws.cloudtrail.user_identity.type`, and `aws.cloudtrail.user_identity.access_key_id` to identify who made the change.
49 - Validate whether this user or role is authorized to modify S3 bucket policies.
50 - Examine `source.ip`, `source.geo`, and `user_agent.original` to identify unusual sources or tools (e.g., CLI or SDK-based activity).
51
52- **Analyze the Bucket Policy Content**
53 - Extract the full JSON from `aws.cloudtrail.request_parameters`.
54 - Look for `Effect=Allow` statements paired with `Principal:"*"`.
55 - Identify what permissions were granted — for example:
56 - `s3:GetObject` (read access to all objects)
57 - `s3:PutObject` or `s3:*` (read/write access)
58 - Check if the policy also contains any `Effect=Deny` statements targeting `Principal:"*"`.
59 If present, determine whether these statements fully restrict public access, if so this alert can be closed.
60
61- **Assess the Impact and Scope**
62 - Review `aws.cloudtrail.resources.arn` to confirm which bucket was affected.
63 - Determine if the bucket contains sensitive, regulated, or internal data.
64 - Check for `PutPublicAccessBlock` or `DeleteBucketPolicy` events in close proximity, as attackers often disable protections first.
65
66- **Correlate with Related Activity**
67 - Review CloudTrail for `GetObject` or `ListBucket` events following the policy change to identify possible data access.
68 - Look for policy changes across multiple buckets by the same actor, suggesting scripted or automated misuse.
69
70- **Validate Intent**
71 - Contact the bucket owner or application owner to determine whether this change was part of a legitimate operation (e.g., website hosting or public dataset publishing).
72 - Review change management logs or ticketing systems for documented approval.
73
74### False positive analysis
75
76- **Intended Public Access**
77 - Buckets used for static websites, documentation hosting, or public datasets may legitimately contain `Principal:"*"`.
78 - Verify such use cases are covered by organizational policies and hardened with least-privilege permissions (e.g., read-only).
79
80- **Effect=Deny Condition**
81 - This rule does not currently exclude cases where `Principal:"*"` appears under both `Effect=Allow` and `Effect=Deny`.
82 - Analysts should review the bucket policy JSON to confirm whether `Deny` statements restrict the same resources.
83 - If access remains blocked to unauthorized entities, the alert can be dismissed as a false positive.
84
85- **Automation or Pipeline Behavior**
86 - Some automated pipelines or templates (e.g., Terraform, CloudFormation) create temporary policies with `Principal:"*"` for bootstrap access.
87 Review timing, user agent, and role identity for expected automation patterns.
88
89### Response and remediation
90
91- **Containment**
92 - If exposure is unauthorized, immediately remove the public access policy using:
93 - `aws s3api delete-bucket-policy` or restore from version control.
94 - Re-enable Block Public Access at the account and bucket levels.
95
96- **Investigation and Scoping**
97 - Review CloudTrail and S3 access logs to identify whether external IPs accessed bucket objects after the policy change.
98 - Search for similar policy updates across other buckets in the same account or region.
99 - Validate AWS Config history for baseline deviations and determine how long the bucket was publicly exposed.
100
101- **Recovery and Hardening**
102 - Reinstate the intended bucket policy from backups or version control.
103 - Implement AWS Config rules:
104 - `s3-bucket-public-read-prohibited`
105 - `s3-bucket-public-write-prohibited`
106 - Restrict `s3:PutBucketPolicy` permissions to trusted administrative roles.
107 - Apply service control policies (SCPs) that prevent policies containing `Principal:"*"` unless explicitly approved.
108 - Enable continuous monitoring through AWS Security Hub or GuardDuty for any new public exposure events.
109
110### Additional information
111 - **[AWS IR Playbooks](https://github.com/aws-samples/aws-incident-response-playbooks/blob/c151b0dc091755fffd4d662a8f29e2f6794da52c/playbooks/)**
112 - **[AWS Customer Playbook Framework](https://github.com/aws-samples/aws-customer-playbook-framework/tree/a8c7b313636b406a375952ac00b2d68e89a991f2/docs)**
113 - **Security Best Practices:** [AWS Knowledge Center – Security Best Practices](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/).
114"""
115references = [
116 "https://stratus-red-team.cloud/attack-techniques/AWS/aws.exfiltration.s3-backdoor-bucket-policy/",
117 "https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html",
118]
119risk_score = 47
120rule_id = "618bb351-00f0-467b-8956-8cace8b81f07"
121severity = "medium"
122tags = [
123 "Domain: Cloud",
124 "Data Source: AWS",
125 "Data Source: Amazon Web Services",
126 "Data Source: AWS S3",
127 "Use Case: Threat Detection",
128 "Tactic: Exfiltration",
129 "Tactic: Collection",
130 "Resources: Investigation Guide",
131]
132timestamp_override = "event.ingested"
133type = "eql"
134
135query = '''
136info where event.dataset == "aws.cloudtrail"
137 and event.provider == "s3.amazonaws.com"
138 and event.action == "PutBucketPolicy"
139 and event.outcome == "success"
140 and stringContains(aws.cloudtrail.request_parameters, "Effect=Allow")
141 and stringContains(aws.cloudtrail.request_parameters, "Principal=\\*")
142'''
143
144
145[[rule.threat]]
146framework = "MITRE ATT&CK"
147[[rule.threat.technique]]
148id = "T1537"
149name = "Transfer Data to Cloud Account"
150reference = "https://attack.mitre.org/techniques/T1537/"
151
152
153[rule.threat.tactic]
154id = "TA0010"
155name = "Exfiltration"
156reference = "https://attack.mitre.org/tactics/TA0010/"
157[[rule.threat]]
158framework = "MITRE ATT&CK"
159[[rule.threat.technique]]
160id = "T1530"
161name = "Data from Cloud Storage"
162reference = "https://attack.mitre.org/techniques/T1530/"
163
164
165[rule.threat.tactic]
166id = "TA0009"
167name = "Collection"
168reference = "https://attack.mitre.org/tactics/TA0009/"
169
170[rule.investigation_fields]
171field_names = [
172 "@timestamp",
173 "user.name",
174 "user_agent.original",
175 "source.ip",
176 "aws.cloudtrail.user_identity.arn",
177 "aws.cloudtrail.user_identity.type",
178 "aws.cloudtrail.user_identity.access_key_id",
179 "aws.cloudtrail.resources.arn",
180 "aws.cloudtrail.resources.type",
181 "event.action",
182 "event.outcome",
183 "cloud.account.id",
184 "cloud.region",
185 "aws.cloudtrail.request_parameters",
186 "aws.cloudtrail.response_elements",
187]
Triage and analysis
Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to your specific environment and operational needs.
Investigating AWS S3 Bucket Policy Added to Allow Public Access
This rule detects modifications to Amazon S3 bucket policies using the PutBucketPolicy API where both Effect=Allow
and Principal:"*" are present. This effectively grants permissions to all AWS identities, including unauthenticated users.
Such exposure can result in sensitive data leaks, ransomware staging, or unauthorized data collection.
This rule focuses on policy-based exposure rather than ACL-based or block-public-access configurations.
It will still trigger if a bucket policy includes both Effect=Allow and Effect=Deny statements that contain Principal:"*". Those cases should be reviewed to confirm whether the Deny statement restricts access sufficiently.
Possible investigation steps
-
Identify the Actor
- Review
aws.cloudtrail.user_identity.arn,aws.cloudtrail.user_identity.type, andaws.cloudtrail.user_identity.access_key_idto identify who made the change. - Validate whether this user or role is authorized to modify S3 bucket policies.
- Examine
source.ip,source.geo, anduser_agent.originalto identify unusual sources or tools (e.g., CLI or SDK-based activity).
- Review
-
Analyze the Bucket Policy Content
- Extract the full JSON from
aws.cloudtrail.request_parameters. - Look for
Effect=Allowstatements paired withPrincipal:"*". - Identify what permissions were granted — for example:
s3:GetObject(read access to all objects)s3:PutObjectors3:*(read/write access)
- Check if the policy also contains any
Effect=Denystatements targetingPrincipal:"*".
If present, determine whether these statements fully restrict public access, if so this alert can be closed.
- Extract the full JSON from
-
Assess the Impact and Scope
- Review
aws.cloudtrail.resources.arnto confirm which bucket was affected. - Determine if the bucket contains sensitive, regulated, or internal data.
- Check for
PutPublicAccessBlockorDeleteBucketPolicyevents in close proximity, as attackers often disable protections first.
- Review
-
Correlate with Related Activity
- Review CloudTrail for
GetObjectorListBucketevents following the policy change to identify possible data access. - Look for policy changes across multiple buckets by the same actor, suggesting scripted or automated misuse.
- Review CloudTrail for
-
Validate Intent
- Contact the bucket owner or application owner to determine whether this change was part of a legitimate operation (e.g., website hosting or public dataset publishing).
- Review change management logs or ticketing systems for documented approval.
False positive analysis
-
Intended Public Access
- Buckets used for static websites, documentation hosting, or public datasets may legitimately contain
Principal:"*". - Verify such use cases are covered by organizational policies and hardened with least-privilege permissions (e.g., read-only).
- Buckets used for static websites, documentation hosting, or public datasets may legitimately contain
-
Effect=Deny Condition
- This rule does not currently exclude cases where
Principal:"*"appears under bothEffect=AllowandEffect=Deny. - Analysts should review the bucket policy JSON to confirm whether
Denystatements restrict the same resources. - If access remains blocked to unauthorized entities, the alert can be dismissed as a false positive.
- This rule does not currently exclude cases where
-
Automation or Pipeline Behavior
- Some automated pipelines or templates (e.g., Terraform, CloudFormation) create temporary policies with
Principal:"*"for bootstrap access.
Review timing, user agent, and role identity for expected automation patterns.
- Some automated pipelines or templates (e.g., Terraform, CloudFormation) create temporary policies with
Response and remediation
-
Containment
- If exposure is unauthorized, immediately remove the public access policy using:
aws s3api delete-bucket-policyor restore from version control.
- Re-enable Block Public Access at the account and bucket levels.
- If exposure is unauthorized, immediately remove the public access policy using:
-
Investigation and Scoping
- Review CloudTrail and S3 access logs to identify whether external IPs accessed bucket objects after the policy change.
- Search for similar policy updates across other buckets in the same account or region.
- Validate AWS Config history for baseline deviations and determine how long the bucket was publicly exposed.
-
Recovery and Hardening
- Reinstate the intended bucket policy from backups or version control.
- Implement AWS Config rules:
s3-bucket-public-read-prohibiteds3-bucket-public-write-prohibited
- Restrict
s3:PutBucketPolicypermissions to trusted administrative roles. - Apply service control policies (SCPs) that prevent policies containing
Principal:"*"unless explicitly approved. - Enable continuous monitoring through AWS Security Hub or GuardDuty for any new public exposure events.
Additional information
- AWS IR Playbooks
- AWS Customer Playbook Framework
- Security Best Practices: AWS Knowledge Center – Security Best Practices.
References
Related rules
- AWS S3 Bucket Policy Added to Share with External Account
- AWS SNS Rare Protocol Subscription by User
- AWS S3 Bucket Replicated to Another Account
- AWS S3 Bucket Enumeration or Brute Force
- Potential AWS S3 Bucket Ransomware Note Uploaded