Restricting access to the S3 bucket outside the application
Hello, I did some research and found different ways to tackle this. You can pick the one that suits your situation best.
Here are the options I found:
- Keep your bucket private and set some policies to restrict access (We’ll explore this option in this post)
- Keep your bucket private and create an endpoint in your api for your authenticated users, create a signed url (it will have expiration time and access token which provides access to s3 object) and return it to user.
- Set your bucket as public and add a lambda function to blur images or return dummy image if request doesn’t have token
Using Bucket Policies:
Step 1: Go to S3 Bucket Permissions tab and edit Block public access (bucket settings) as follow:
Step 2: Change your bucket policy as below:
{
"Version": "2012–10–17",
"Id": "Restrict Access",
"Statement": [
{
"Sid": "Restrict accessing from outside of domain",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:Get*",
"Resource": "arn:aws:s3:::your-bucket/*",
"Condition": {
"StringNotLike": {
"aws:Referer": ["http://www.example.com/*", "http://www.example.com/"]
}
}
},
{
"Sid": "Allow GET requests",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:Get*",
"Resource": "arn:aws:s3:::your-bucket/*"
}
]
}
When a client makes a request to access an object in the S3 bucket, the S3 service evaluates the bucket policy.
If the referer does not match any of the allowed domains, the first statement's condition is met, and the "Restrict accessing from outside of the domain" statement applies. In this case, the request is denied, and the client cannot access the object.
Ensure that your request includes a ‘Referer’ header when accessing the bucket; otherwise, the statement won’t be met, and you won’t be able to access the content in your bucket.
You can customize the ‘Condition’ based on your specific requirements. For example, you can restrict access from mobile devices by adding the following condition to your ‘Deny’ statement:
"Condition": {
"StringLike": {
"aws:UserAgent": "*Mobile*"
}
}
I hope it will be useful as you work on securing your user avatars. Happy coding!