Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

S3 POST upload minimal policy

I have successfully created a simple HTML form that POSTs an uploaded file to my Amazon S3 bucket. I followed these instructions: http://aws.amazon.com/articles/1434

Now I am trying to create the minimal policy on a user that can perform the HTML form POST.

Here's the setup:

userID: s3-uploader<br/>
ACCESS-KEY-ID: AXAXAXAXAXAXAXAXAXAX

Here's the HTML form:

<!DOCTYPE html>
<html>
<head>
    <title>S3 POST Form</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="https://<cname-for-upload-bucket>/" method="post" enctype="multipart/form-data">
    <input type="hidden" name="key" value="foo/${filename}">
    <input type="hidden" name="AWSAccessKeyId" value="AXAXAXAXAXAXAXAXAXAX">
    <input type="hidden" name="acl" value="private">
    <input type="hidden" name="success_action_redirect"
           value="https://s3.amazonaws.com/<bucket-01-name>/upload-success.html">
    <input type="hidden" name="policy"   
value="eyJleHBpcmF0aW9uIjogIjIwMTQtMTItMTNUMDA6MDA6MDBaIiwKICAgICJjb25kaXRpb25zIjogWwogICAgICAgIHsiYnVja2V0IjogInMzLXVwLmdyaWR3YXJkLm5ldCJ9LAogICAgICAgIFsic3RhcnRzLXdpdGgiLCAiJGtleSIsICJwZWQvIl0sCiAgICAgICAgeyJhY2wiOiAicHJpdmF0ZSJ9LAogICAgICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL2dkd2QvdXBsb2FkLXN1Y2Nlc3MuaHRtbCJ9LAogICAgICAgIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICIiXSwKICAgICAgICBbImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwgMCwgMTA0ODU3Nl0KICAgIF0KfQ==">
    <input type="hidden" name="signature" value="WnbMCo0OY7g8oYkfxrVb8np4l94=">
    <input type="hidden" name="Content-Type" value="image/jpeg">
    <!-- Include any additional input fields here -->

    File to upload to S3:
    <input name="file" type="file">
    <br>
    <input type="submit" value="Upload File to S3">
</form>
</body>
</html>

...and then I have this is the unencoded version of the form hidden input 'policy':

{"expiration": "2014-12-13T00:00:00Z",
    "conditions": [
        {"bucket": "<cname-for-upload-bucket>"},
        ["starts-with", "$key", "foo/"],
        {"acl": "private"},
        {"success_action_redirect": "https://s3.amazonaws.com/<bucket-01-name>/upload-success.html"},
        ["starts-with", "$Content-Type", ""],
        ["content-length-range", 0, 1048576]
    ]
}

This all works when userId: s3-uploader has a policy of:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}

...but if I change the policy to be something more explicit, but still seemingly reasonable I get an <AccessDenied/> message back from the exact same HTML form post.

Here's the more restrictive policy I tried:

{
    "Statement": [
        {
            "Sid": "AllowS3uploader",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:PutBucketAcl",
                "s3:PutBucketPolicy",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::<cname-for-upload-bucket>",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::756342427722:user/s3-uploader"
                ]
            }
        }
    ]
}

I've read through the doc here, without obtaining additional clarity:
http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingIAMPolicies.html

So I ask my fellow Overflow-ites, what am I missing? I'd really rather not have the s3-uploader userId able to do any action (i.e. 's3:*') on the bucket.

like image 851
Oort Avatar asked Feb 06 '13 06:02

Oort


1 Answers

The ARN that you're using in the Resource section is wrong, you must use the actual bucket name instead of the CNAME entry.

like image 61
Ja͢ck Avatar answered Nov 15 '22 07:11

Ja͢ck