I'm building a website where users can upload files directly to amazon s3. I temporarily sign a url w/ my secret key that grants the user temporary PUT access to my site. This is possible through the CORS configuration.
Now, once the files are up there I want no one to read them but me. The current bucket policy I have disallows everyone from reading objects including me, the admin. Which is not good. What bucket policy will help me here?
Here is my working CORS.
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://url.com</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
UPDATE: Works with this policy:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Deny",
"NotPrincipal": {
"AWS":"arn:aws:iam::123456789012:user/Bob"
}
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<bucket>/*"
}
]
}
Ok we created an IAM user with full permission to S3, we use this user to sign the temporary policies to allow the upload. The User policy for the user is (You could further restrict this user to allow access to only one bucket, or even further to allow the user only put permissions on the bucket):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
We then create a temporary policy to allow an upload into our useruploads bucket
{ "expiration": "2013-11-20T12:00:00.000Z",
"conditions": [
{"bucket": "useruploadtest"},
["starts-with", "$key", "russ"],
{"acl": "public-read"},
{"success_action_redirect": "http://localhost/successful_upload.html"},
["starts-with", "$Content-Type", "image/"],
]
}
We then sign the base64 encoded policy with our secret key (this code below is a sample of creating the signature with cryptojs never put your secret key in client side code)
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js"> </script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
<script>
var hash = CryptoJS.HmacSHA1("eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTAxVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJ1c2VydXBsb2FkdGVzdCJ9LA0KICAgIFsic3RhcnRzLXdpdGgiLCAiJGtleSIsICJydXNzIl0sIA0KICAgIHsiYWNsIjogInB1YmxpYy1yZWFkIn0sIA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL2xvY2FsaG9zdC9zdWNjZXNzZnVsX3VwbG9hZC5odG1sIn0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkQ29udGVudC1UeXBlIiwgImltYWdlLyJdLA0KICBdDQp9", "YourSecretKeyHere");
var base64 = CryptoJS.enc.Base64.stringify(hash);
console.log(base64);
</script>
Then you can use the signed policy to allow a temporary upload
<form action="http://useruploadtest.s3.amazonaws.com" method="post" enctype="multipart/form-data">
<input type="hidden" name="acl" value="public-read" />
<input type="hidden" name="success_action_redirect" value="http://localhost/successful_upload.html" />
<input type="hidden" name="AWSAccessKeyId" value="AKIAJM3U7AMGF6J6YYWQ" />
<input type="hidden" name="Policy" value="eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTAxVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJ1c2VydXBsb2FkdGVzdCJ9LA0KICAgIFsic3RhcnRzLXdpdGgiLCAiJGtleSIsICJydXNzIl0sIA0KICAgIHsiYWNsIjogInB1YmxpYy1yZWFkIn0sIA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL2xvY2FsaG9zdC9zdWNjZXNzZnVsX3VwbG9hZC5odG1sIn0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkQ29udGVudC1UeXBlIiwgImltYWdlLyJdLA0KICBdDQp9" />
<input type="hidden" name="Signature" value="Db4K65tz/WJtjAUUCWRn5MXdAJ4=" />
Key to upload: <input type="input" name="key" value="test.jpg" /><br />
Content-Type: <input type="input" name="Content-Type" value="image/jpeg" /><br />
File: <input type="file" name="file" /> <br />
<input type="submit" name="submit" value="Upload to Amazon S3" />
</form>
So long as the bucket in our case "useruploadtest" allows read access from another IAM user which we use in our application to read the files and process them it all works.
Hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With