Description
Wildcards in Action and Principal can authorize unintended operations or principals. s3:* represents all S3 actions, while s3:Get* represents only a subset. Effective permissions also depend on Resource, conditions, explicit denies, and Block Public Access. A policy scoped only to object ARNs does not grant every bucket administration action.
Potential impact
- Read permissions may expose object contents to principals that do not need access.
- Write or delete permissions may allow unwanted uploads, changes to object contents, or data loss.
- Excessive permissions can disrupt deployments and services using the storage. The impact depends on the actual actions and resources allowed.
Remediation
- Specify the necessary actions, principals, and resource ARNs, and narrow unnecessary wildcards. Even when public reads are required, restrict write and administration permissions separately.
- Check conditions, explicit denies, and account and bucket Block Public Access together. A
privateACL does not cancel access granted by a bucket policy. - Apply the policy using resources supported by your provider and module versions. S3 module 3.7.0 requires
attach_policy = truefor a custom policy. Test that required access remains available and unapproved access is denied.
Legacy policy examples
These older inline examples illustrate the difference in action scope. AWS provider 4.2.0 documents policy and acl as read-only, requiring a separate policy resource with that version. Check current Object Ownership and Block Public Access requirements for new buckets too. Use an available unique bucket name and do not apply both alternatives together.
Allow all object actions
resource "aws_s3_bucket" "open_bucket" {
bucket = "example-s3b-181355"
acl = "private"
policy = <<EOF
{
"Id": "id113",
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::example-s3b-181355/*",
"Principal": "*"
}
]
}
EOF
}
The policy allows wildcard principals to perform all S3 actions applicable to the object ARN scope. acl = "private" does not cancel that grant. This is distinct from granting every bucket administration action.
Narrow only the action to object writes
resource "aws_s3_bucket" "restricted_bucket" {
bucket = "example-s3b-181355"
acl = "private"
policy = <<EOF
{
"Id": "id113",
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:putObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::example-s3b-181355/*",
"Principal": "*"
}
]
}
EOF
}
The action scope is narrower, but object writes are still granted to Principal: "*". AWS action names are case-insensitive, so s3:putObject is a write permission too. This does not resolve public writes; further restrict access to approved principals and the objects they need.
References
- CWE-250
- AWS S3 bucket resource
- AWS policy Action element
- AWS policy Principal element
- AWS policy Effect element
- Permissions and resource types for S3 operations
- S3 Block Public Access
- S3 bucket naming rules
- S3 bucket attributes in AWS provider 4.2.0
- Policy handling in S3 module 3.7.0
- Input defaults in S3 module 3.7.0