-1

I am in serious trouble. I have been uploading to the s3 bucket using aws-sdk javascript, downloading it through object link. Using s3 to store images/assets to be used for the nextjs website. I have set the bucket to the read only for everyone. I just realize that this is serious problem, as anyone will be able to download from my bucket unilimited time, and the cost will be through the roof. How can I secure the download to be only from my website through presigned link(I haven't configured the presigned link on my side)? Please help me. I will provide more details below:

current bucket policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::bucketname/*"
        }
    ]
}

CORS:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE",
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "x-amz-server-side-encryption",
            "x-amz-request-id",
            "x-amz-id-2"
        ],
        "MaxAgeSeconds": 3000
    }
]
NroGamerz
  • 189
  • 2
  • 8

1 Answers1

1

You can restrict access to objects based on the 'referring' website.

From Bucket policy examples - Amazon Simple Storage Service:

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Effect":"Allow",
      "Principal":"*",
      "Action": "s3:GetObject",
      "Resource":"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
      "Condition":{
        "StringLike":{"aws:Referer":["http://www.example.com/*","http://example.com/*"]}
      }
    }
  ]
}

However, restricting access with referer is not secure since it is easy to fake this information.

The more secure method would be to use Amazon S3 pre-signed URLs, which provide time-limited access to private objects in Amazon S3. These URLs must be generated by your back-end, typically after a user has authenticated to your website. This is ideal for serving private/confidential content.

However, if you are simply serving content for a normal website that does not require authentication, then referer is more appropriate.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • thank you for your answer. Is it possible to pass the object link to the presigned url getObject rather than the object name itself? Also what will be the general expiration period for website served assets? – NroGamerz Dec 03 '22 at 11:59
  • 1
    You must write code that generates the pre-signed URL. You can use an AWS SDK to do it (eg [Getting s3 pre-signed URLS using the Node.js AWS SDK v3](https://daniel.feldroy.com/posts/2022-06-18-s3-getsigned-url-nodejs-aws-sdk-3)). When generating the URL, you can specify the expiry period (eg 5 minutes). – John Rotenstein Dec 03 '22 at 21:46