Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use a link to an image in my AWS S3 bucket on my webpage?

I have an image in my AWS S3 bucket. Is it safe to include this image in my website by placing the AWS URL in an <img> tag? The URL includes parameters such as "Amz-Signature", "Amz-Credential", and "amz-security-token. Could these be used maliciously to get to access other files in my S3 bucket?

Here is an example URL:

https://s3.amazonaws.com/MyBucketName/FileName.jpg?X-Amz-Date=20160126T141139Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=Lots_of_letters_and_Numbers2&X-Amz-Credential=MYAMAZON_CREDENTIALS/20160126/us-east-1/s3/aws4_request&X-Amz-SignedHeaders=Host&x-amz-security-token=REALLY_LONG_SECURITYTOKEN

Alternatively, I can generate an expiry URL from my C# code using the AWS SDK. Something like:

var expiryUrlRequest = new GetPreSignedUrlRequest
{
    BucketName = WebConfigurationManager.AppSettings["AWSBucketName"],
    Key = fileName,
    Expires = DateTime.Now.AddHours(3)
};

This yields a URL that has "AWSAccessKeyId" as a parameter.

Are either of these URL's safe to use in my webpage? What risks would be involved in using them on my site?

Thank you very much for your time. Please let me know if you need additional information or if I am being unclear.

EDIT: To provide some further insight into my application, users are uploading a file to an S3 bucket. I'm using SignalR to confirm that the image is in the bucket by displaying the image from S3 on my webpage for the user to see.

like image 842
user95227 Avatar asked Jan 26 '16 14:01

user95227


People also ask

How do I show an image from my Amazon S3 on my website?

Easiest thing to do is make them public in s3, at least read-only. If you don't want them to be public on s3, for whatever reason, you could add a cloudfront distribution that will serve the images from your s3 bucket, and you can give cloudfront access to the files, without making the images public in s3.

How secure is S3 signed URL?

There is an access check on the S3 side but that only checks whether the signer entity is allowed to get the file. You can remove that permission but that invalidates all signed URLs. Signed URLs provide secure a way to distribute private content without streaming them through the backend.

Is S3 good for images?

The more efficient and cost-effective option is to use AWS's S3 service for storing the image files. Using S3 is a very low-cost option. Effectively, all you are paying for is transferring files into an S3 bucket and serving those images to your users.


1 Answers

Do not make the bucket public. If you do, then potentially user1 could see user2's uploaded files.

You can allow users to retrieve single files for a specific period of time using pre-signed URLs.

  1. Mark the S3 bucket as private.
  2. Use GetPreSignedUrlRequest to generate a pre-signed URL for the file you want the user to download.
  3. Use that URL in your <img> tag.

Using this technique is safe:

  1. The user can only download the file during the timeframe that you permit, until the expiration date (which you set as part of the GetPreSignedUrlRequest call)
  2. The credentials you see in the URL are may be the same as those that were used to create the URL. But they are safe to show the user.
  3. The user cannot download any other files from the bucket.

The URL uses a hashing technique to ensure the URL cannot be modified, nor can it be abused to get other files.

If displaying the access key ID is a concern, you can either (a) create an IAM user specifically for the purpose of downloading the files from S3, or (b) use an IAM role on your EC2 instance to generate the pre-signed URL.

References:

  • http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURL.html
like image 127
Matt Houser Avatar answered Sep 28 '22 06:09

Matt Houser