S3 bucket policy multiple conditions - amazon-s3

I'm looking to grant access to a bucket that will allow instances in my VPC full access to it along with machines via our Data Center. Without the aws:SouceIp line, I can restrict access to VPC online machines.
I need the policy to work so that the bucket can only be accessible from machines within the VPC AND from my office.
{
"Version": "2012-10-17",
"Id": "Policy1496253408968",
"Statement": [
{
"Sid": "Stmt1496253402061",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"StringLike": {
"aws:sourceVpc": "vpc-dcb634bf",
"aws:SourceIp": "<MY PUBLIC IP>"
}
}
}
]
}

You can generate a policy whose Effect is to Deny access to the bucket when StringNotLike Condition for both keys matches those specific wildcards.
{
"Version": "2012-10-17",
"Id": "Policy1496253408968",
"Statement": [
{
"Sid": "Stmt1496253402061",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"StringNotLike": {
"aws:sourceVpc": "vpc-dcb634bf",
"aws:SourceIp": "<MY PUBLIC IP>"
}
}
}
]
}
The second condition could also be separated to its own statement. AWS applies a logical OR across the statements. 1
{
"Version": "2012-10-17",
"Id": "Policy1496253408968",
"Statement": [
{
"Sid": "Stmt1496253402061",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"StringLike": {
"aws:sourceVpc": "vpc-dcb634bf",
}
}
},
{
"Sid": "Stmt1496253402062",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"StringLike": {
"aws:SourceIp": "<MY PUBLIC IP>"
}
}
}
]
}

AWS has predefined condition operators and keys (like aws:CurrentTime). Individual AWS services also define service-specific keys.
As an example, assume that you want to let user John access your Amazon SQS queue under the following conditions:
The time is after 12:00 p.m. on 7/16/2019
The time is before 3:00 p.m. on 7/16/2019
The request comes from an IP address within the range 192.0.2.0 to 192.0.2.255 or 203.0.113.0 to 203.0.113.255.
Your condition block has three separate condition operators, and all three of them must be met for John to have access to your queue, topic, or resource.
The following shows what the condition block looks like in your policy. The two values for aws:SourceIp are evaluated using OR. The three separate condition operators are evaluated using AND.
"Condition" : {
"DateGreaterThan" : {
"aws:CurrentTime" : "2019-07-16T12:00:00Z"
},
"DateLessThan": {
"aws:CurrentTime" : "2019-07-16T15:00:00Z"
},
"IpAddress" : {
"aws:SourceIp" : ["192.0.2.0/24", "203.0.113.0/24"]
}
}
reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_multi-value-conditions.html

this is an old question, but I think that there is a better solution with AWS new capabilities. Especially, I don't really like the deny / StringNotLike combination, because denying on an s3 policy can have unexpected effects such as locking your own S3 bucket down, by denying yourself (this could only be fixed by using the root account, which you may not have easily accessible in a professional context)
So the solution I have in mind is to use ForAnyValue in your condition (source). e.g something like this:
{
"Version": "2012-10-17",
"Id": "Policy1496253408968",
"Statement": [
{
"Sid": "Stmt1496253402061",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"ForAnyValue:StringEquals": {
"aws:sourceVpc": [
"vpc-dcb634bf",
"<MY PUBLIC IP>"
]
}
}
}
]
}

Related

AWS S3 bucket policy to block source IP address not working

I know this question has been asked a few times and I have gone through a some documents and examples on this. But I am still not able to get it working.
I want to block access to my S3 bucket from one particular IP address and allow all others. I do not want to block instances belonging to an IAM role and hence I am using NotIpAddress Condition for this. Below is the policy I applied on my bucket:
{
"Version": "2012-10-17",
"Id": "Policy1486984747194",
"Statement": [
{
"Sid": "AllowAllExceptOneIP",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-test-bucket",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "52.38.90.46"
}
}
}
]
}
But this policy isn't working. I am able to upload files to my bucket from this machine, I am using s3-curl.pl to temporarily upload my files.
Can someone please help me find what is wrong here. Thanks.
To block all actions to an S3 bucket from a particular IP, policy needs to have separate deny effect statement for that IP, sample:
{
"Version": "2012-10-17",
"Id": "Policy1487062767078",
"Statement": [
{
"Sid": "AllowAll",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
]
},
{
"Sid": "DenyIP",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.38.90.46"
}
}
}
]
}
Action and Resource can be changed based on what one needs to block.
Thanks a lot #SergeyKovalev for helping me with this solution.

Amazon S3 : How to allow access to a specific path, only for a specific referer?

I have a Amazon S3 bucket mybucket and only want to enable access to content in a specific nested folder (or in S3 terms, with a specific "prefix").
I tried the following S3 bucket policy but it doesn't work. After adding the condition I started getting access denied errors in the browser.
{
"Version": "2012-10-17",
"Id": "Policy for mybucket",
"Statement": [
{
"Sid": "Allow access to public content only from my.domain.com",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/public/content/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://my.domain.com/*"
]
}
}
}
]
}
What should the policy look like to achieve this?
You need to split the policy in to two statements. One to allow access to the folder (prefix), and one to deny access when the referer is not one of the white listed domains:
{
"Version": "2012-10-17",
"Id": "Policy for mybucket",
"Statement": [
{
"Sid": "Allow access to public content",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/public/content/*"
},
{
"Sid": "Deny access to public content when not on my.domain.com",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/public/content/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"http://my.domain.com/*"
]
}
}
}
]
}

s3 bucket policy to add exception

Hi I am trying to write the permissions policy to access my bucket.
I want to deny access to a particular user-agent and allow access to all other user agents. With the below policy the access is getting denied to all.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1456658595000",
"Effect": "Deny",
"Action": [
"s3:*"
],
"Condition": {
"StringLike": {
"aws:UserAgent": "NSPlayer"
}
},
"Resource": [
"arn:aws:s3:::bucket/"
]
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::bucket/*"
]
}
]
}
Please let me know how should I write such policy so that except one user agent all others are able to access the same.
It has to be written this way!
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SID",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Condition": {
"StringNotLike": {
"aws:UserAgent": "NSPlayer"
}
},
"Resource": [
"*"
]
}
]
}
This solution works if bucket objects are not public read/write. One related answer is here: Deny access to user agent to access a bucket in AWS S3

Using two policies together in a single S3 bucket

I am new to Amazon S3 and just created my first bucket. I need two important policies to be implemented on the bucket which are as follows:
First, policy for allowing only downloads from my own website (via HTTP referrer)
Secondly, I want to make all objects in the bucket public.
I have got two different codes of policies for my needs, but now I can't put them together to achieve the said goals. Please help me joining these too policies together so I achieve what I want.
For allowing referrer downloads:
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests originated from www.example.com and example.com",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"URL/*",
]
}
}
}
]
}
For making objects public:
{
"Sid": "...",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket/*",
"Principal": {
"AWS": [ "*" ]
}
}

amazon S3 bucket policy - restricting access by referer BUT not restricting if urls are generated via query string authentication

I have the following bucket policy set on my bucket:
{
"Version": "2008-10-17",
"Id": "My access policy",
"Statement": [
{
"Sid": "Allow only requests from our site",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my_bucket/*",
"Condition": {
"StringLike": {
"aws:Referer": [
" http://example.com/*",
" http://www.example.com/*"
]
}
}
},
{
"Sid": "Dont allow direct acces to files when no referer is present",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my_bucket/*",
"Condition": {
"Null": {
"aws:Referer": true
}
}
}
]
}
I also configured query string authentication, but it looks like I can't have both. If I have my bucket policies set to deny any request that doesn't originate from example.com, my temporary url using query string authentication will also not get served. So my question is, how can i have both ? Is there a way to check for url parameters and see if it has a parameter called "Signature" and in that case not apply the referer policy?
Remove the space in the referrers string " http://example.com/*" that's wrong... the Amazon examples made that mistake too (using "mydomain" instead of "example").
For the second statement the easier way to solve it is to remove that entire statement and have your files permissions (ACLs) set to private (Owner-Read/Write and World-NoRead/NoWrite)
I am not sure, but in appears that even if you have a Deny Statement a file can still be read if it has a public permission (World Read).
Also, if you are distributing the files on CloudFront remember to allow it to read the bucket too. So a complete bucket policy will look like:
{
"Version": "2008-10-17",
"Id": "YourNetwork",
"Statement": [
{
"Sid": "Allow get requests to specific referrers",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucket/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.yourwebsite.com/*",
"http://yourwebsite.com/*"
]
}
}
},
{
"Sid": "Allow CloudFront get requests",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::12345678:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucket/*"
}
]
}
(change the 12345678 to your AWS account ID number without the dashes)