4

I'm trying to restrict my bucket to deny everything, but allow uploads from one specific IAM user and get objects based on referer header. Here is my policy:

{
    "Version": "2012-10-17",
    "Id": "Meteor refer policy",
    "Statement": [
        {
            "Sid": "allow upload",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::556754141176:user/username"
            },
            "Action": "s3:PutObject*",
            "Resource": [
                "arn:aws:s3:::bucketname",
                "arn:aws:s3:::bucketname/*"
            ]
        },
        {
            "Sid": "Allow get",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "bucketname/*",
            "Condition": {
                "StringLike": {
                    "aws:Referer": [
                        "http://myapp.com*",
                        "http://localhost*"
                    ]
                }
            }
        },
        {
            "Sid": "Explicit deny",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "bucketname/*",
            "Condition": {
                "StringNotLike": {
                    "aws:Referer": [
                        "http://myapp.com*",
                        "http://localhost*"
                    ]
                }
            }
        }
    ]
}

This policy correctly enforces the GetObject directive to only the referer header, but I'm not able to upload anything with that user like I stated. If I take out the explicit deny, I can access the object from anywhere and the referer doesn't matter. What is wrong with my policy? Also, I can't access anything in the bucket from the console. What do I need to do for that?

Thanks,

gkrizek
  • 978
  • 3
  • 10
  • 18

1 Answers1

5

By default, all content in an Amazon S3 bucket is private. So, just add access to users that should be permitted.

Also, merely granting PutObject will only allow that API call and will not permit access via the AWS Management Console, which requires permissions like ListAllMyBuckets. So, make sure the uploading user either has the necessary permissions, or only uses the API calls that it are permitted.

Therefore:

  • Remove the Deny policy -- it is not required
  • In the GetObject policy, you should also remove "Resource": "bucketname/*", because that is explicit in the fact that the Bucket Policy applies to the bucket to which it is attached
  • Have the uploading user use the AWS Command-Line Interface (CLI) or a web page to upload, that only requires PutObject OR grant additional permissions to be able to use the AWS Management Console for Amazon S3 (shown below)

Here is a set of permissions that would grant upload access within the Amazon S3 management console (with thanks to Is there an S3 policy for limiting access to only see/access one bucket?):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::bucketname"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        }
    ]
}
John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • Thanks for the explanation! I knew S3 buckets were by default private but whenever I removed the explicit deny, you could see the photos from anywhere. I figure out that this was because of the ACL that my third part tool was using to upload with gave everyone read access. I think I just spun myself in circles with ACLs and Policies. Thanks for the explanation! Just out of curiosity, why does AWS suggest to have an explicit deny in this article? http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-4 – gkrizek Oct 06 '16 at 10:46
  • I don't think the article is "suggesting" its use -- rather, it's saying that you could use an explicit deny if you wish to also override any other rules. The example I like to use is... Let's say Sys Admins have permission to view all S3 buckets, but you have an HR bucket that you want accessible only to HR staff. You could grant HR staff access to the HR bucket, then use an Explicit Deny to block anyone else from accessing it, even if they've been separately granted access (such as the Sys Admins). – John Rotenstein Oct 07 '16 at 00:52
  • Thank you for the explanation. That makes sense! – gkrizek Oct 07 '16 at 14:25