I am trying to write bucket policies to deny public access to buckets and objects using the AWS's defense-in-depth methodology as per How to Use Bucket Policies and Apply Defense-in-Depth to Help Secure Your Amazon S3 Data | AWS Security Blog.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnSecureCommunications",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::ironman111",
"arn:aws:s3:::ironman111/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Sid": "DenyPublicReadACL",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::ironman111/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": [
"public-read",
"public-read-write",
"authenticated-read"
]
}
}
},
{
"Sid": "DenyPublicReadGrant",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::ironman111/*",
"Condition": {
"StringLike": {
"s3:x-amz-grant-read": [
"*http://acs.amazonaws.com/groups/global/AllUsers*",
"*http://acs.amazonaws.com/groups/global/AuthenticatedUsers*"
]
}
}
},,
{
"Sid": "DenyPublicListACL",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutBucketAcl",
"Resource": "arn:aws:s3:::ironman111",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": [
"public-read",
"public-read-write",
"authenticated-read"
]
}
}
},
{
"Sid": "DenyPublicListGrant",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutBucketAcl",
"Resource": "arn:aws:s3:::ironman111",
"Condition": {
"StringLike": {
"s3:x-amz-grant-read": [
"*http://acs.amazonaws.com/groups/global/AllUsers*",
"*http://acs.amazonaws.com/groups/global/AuthenticatedUsers*"
]
}
}
}
]
}
However I don't see this above policy restricting me from making the bucket or object public or its ACLs public read/write.
I have later added the following to the policy. In this case, the resources are private but now I am restricted from sharing S3 buckets between accounts.
{
"Sid": "DenyAuthenticatedUsersAccess",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::ironman111/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-acl": "private"
}
}
},
{
"Sid": "DenyAuthenticatedUsersAccess",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutBucketAcl",
"Resource": "arn:aws:s3:::ironman111",
"Condition": {
"StringNotEquals": {
"s3:x-amz-acl": "private"
}
}
},
Please suggest what is wrong in the first policy.
I am unable to use IAM policy validator as it is a bucket policy. Also, I am unable to test cross-account as I do not have another canonical id.
Why does order matter in the resources array?
Updated:
I have added the following policy to the IAM user and it is still allowing the creation of a bucket with public access.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": [
"s3:CreateBucket",
"s3:PutBucketAcl"
],
"Resource": "*",
"Condition": {
"StringLike": {
"s3:x-amz-acl": [
"public-read",
"public-read-write"
]
}
}
}
]
}
I need the policies to stop buckets from being public.
The first policy is Denying the ability to upload objects with an Access Control List that will make the objects public.
You are correct that the policy will not stop you "from making the bucket or object public or its ACLs public read/write". Rather, it is preventing files being stored as public objects in the first place.
You, as an administrator, could certainly add a Bucket Policy that then makes the whole bucket public. But that is not what the policy is trying to prevent.
Related
I am attempting to deploy a SSM Inventory Collection and a Resource Data Sync via Cloudformation in 15 accounts. I am able to manually add each account by adding a statement in the central s3 bucket for proper access. I was wondering is there a way to create a policy that allows newly created AWS accounts in the future to have proper access without adding a statement to the s3 bucket policy. Below is the documentation I have followed. I was using this method to add each account below
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*/accountid=123456789012/*",
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*/accountid=444455556666/*",
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*/accountid=777788889999/*"
],
https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-inventory-datasync.html
Further in the documentation, I see you can create a resource data sync for accounts defined in AWS Organizations. But this still doesnt accomplish granting any new accounts where template gets deployed, access will be granted.
Creating an inventory resource data sync for accounts defined in AWS Organizations
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SSMBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::S3_bucket_name"
},
{
"Sid": " SSMBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/bucket-prefix/*/accountid=*/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control",
"s3:RequestObjectTag/OrgId": "organization-id",
"aws:SourceAccount": "123456789012"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:ssm:*:123456789012:resource-data-sync/*"
}
}
},
{
"Sid": " SSMBucketDeliveryTagging",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObjectTagging",
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/bucket-prefix/*/accountid=*/*"
]
}
]
}
I have played around with a few policies but doesn't seem to work
{
"Version": "2012-10-17",
"Statement": [
{
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::inventorycollectionsync/*"
],
"Effect": "Allow",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "o-mb7bem0c79"
}
}
}
]
}
Try this:
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SSMBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::bucketname"
},
{
"Sid": " SSMBucketOrgDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucketname/*/accountid=*/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Sid": " SSMBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucketname/*/accountid=*/*",
"Condition": {
"StringEquals": {
"s3:RequestObjectTag/OrgId": "org-id",
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Sid": " SSMBucketDeliveryTagging",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObjectTagging",
"Resource": "arn:aws:s3:::bucketname/*/accountid=*/*"
}
]
}
The below S3 bucket policy to access alb logs from another account of same region with Deny policy doesn't work, I tried with a Condition but no luck
If I use "Allow" it works but I need to use Deny as per my company policy and allow based on condition
127311923021 - us-east-1
Any ideas please?
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "arn:aws:s3:::myelbogs/prefix/*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::myelbogs/prefix/*",
"Condition": {
"StringNotLike": {
"AWS": "arn:aws:iam::127311923021:root"
}
},
},
{
"Effect": "Deny",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::myelbogs/prefix/*",
"Condition": {
"StringNotLike": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
},
},
{
"Effect": "Deny",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::myelbogs",
"Condition": {
"StringNotLike": {
"AWS": "arn:aws:iam::127311923021:root"
}
},
}
]
}
I have restricted the read access on my entire bucket to specific IPs, e.g. 1.1.1.0 & 2.2.2.0 as per the bucket policy given below.
There's a file in it, s3://MYBUCKET/onefile.txt, to which I want to give another set of IPs read access, e.g. to 3.3.3.0 and 4.4.4.0. So that now onefile.txt can only be accessed by 3.3.3.0 and 4.4.4.0 but NOT by 1.1.1.0 & 2.2.2.0 or any other.
How can I accomplish that?
Current Permissions > Bucket Policy (e.g.)
{
"Version": "2012-10-17",
"Id": "http referer policy",
"Statement": [
{
"Sid": "MY RESTRICTED REQUESTS",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"1.1.1.0/20",
"2.2.2.0/22"
]
}
}
}
]
}
Add explicit deny and allow statements for that file onefile.txt in addition to the existing statement in the Policy.
The updated bucket policy would look like,
{
"Version": "2012-10-17",
"Id": "http referer policy",
"Statement": [
{
"Sid": "MY RESTRICTED REQUESTS",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"1.1.1.0/20",
"2.2.2.0/22"
]
}
}
},
{
"Sid": "MY RESTRICTED REQUESTS_1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/onefile.txt",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"3.3.3.0/20",
"4.4.4.0/22"
]
}
}
},
{
"Sid": "MY RESTRICTED REQUESTS_2",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/onefile.txt",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"1.1.1.0/20",
"2.2.2.0/22"
]
}
}
}
]
}
i have the following configuration and I've already tried a lot of things. Can someone check it an say what might be the issue?
I've added the canonical account of the source to the destination bucket.
The replication is enabled on the source bucket. Is replicating the whole bucket.
Source bucket.
"Version": "2012-10-17",
"Id": "PutObjPolicy",
"Statement": [
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::source-bucket/*",
"Condition": {
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
}
},
{
"Sid": "AWSSourcebucketWrite20131101",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::external_account_who_write_the_files:root",
"arn:aws:iam::external_account_who_write_the_files:root",
"arn:aws:iam::external_account_who_write_the_files:root"
]
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::source-bucket/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
Destination bucket
{
"Version": "2012-10-17",
"Id": "PutObjPolicy",
"Statement": [
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::source-bucket-replication/*",
"Condition": {
"Null": {
"s3:x-amz-server-side-encryption": "true"
},
"Bool": {
"aws:SecureTransport": "true"
}
}
},
{
"Sid": "Stmt123",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::source_bucket_account:root"
},
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete"
],
"Resource": "arn:aws:s3:::source-bucket-replication/*",
"Condition": {
"Bool": {
"aws:SecureTransport": "true"
}
}
}
]
}
Did you tried adding new file to your source bucket? Or update an existing file on source bucket? I think replication takes effect only on the items added or updated after enabling replication.
I have created a bucket policy to try and stop hotlinking to my S3 files from people who gain the direct URL. I only want my website to be able to access those files. However when I direct link even with the below policy, it still allows access to the file. The files are all set to public.
{
"Id": "Policy1491040992219",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt14910401236760",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucketname/*",
"Condition": {
"StringLike": {
"aws:Referer": "https://mywebsite.com/*"
}
},
"Principal": "*"
},
{
"Sid": "Stmt14910403436760",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucketname/*",
"Condition": {
"StringLike": {
"aws:Referer": "http://localhost:8888/*"
}
},
"Principal": "*"
}
]
}
Do I need to change any settings on the actual S3 bucket settings to stop all access?
Thanks!
You are missing the Deny statement. Try this policy:
{
"Version": "2008-10-17",
"Id": "Policy1491040992219",
"Statement": [
{
"Sid": "Stmt14910401236760",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://mywebsite.com/*",
"http://localhost:8888/*"
]
}
}
},
{
"Sid": "Stmt14910401236761",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://mywebsite.com/*",
"http://localhost:8888/*"
]
}
}
}
]
}