Image_url and s3 credentials

After uploading a file to S3 and saving its data to my model, I get to call image_url in image tags and such. However…something about having all that credential information as part of a url that I want to be a publicly readable file strikes me as sort of…odd? If my understanding is correct, and it’s used for signing uploads, is there any reason why all this remains in the url? Would this hurt me in any way?

I go to my console and type model.image_url (or just copy image url in the browser) and get this:

https://bucket.s3.region.amazonaws.com/model/1/image/9457719e40fb416e01a153657d7ea4fb.png?X-Amz-Algorithm=###&X-Amz-Credential=accesskey_date_region_s3aws4_request&X-Amz-Date=###&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=###

Is it ok that X-Amz-Algorithm, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders, and X-Amz-Signature are public like this?

X-Amz-Credential is just my access key and date and such, so it doesn’t seem harmful, but what about X-Amz-Signature?

And X-Amz-Expires…what expires here? According to this a value of 900 is equal to 15 minutes, however I’ve been able to view this image hours later. Why would I want this?

Presigned URLs are safe, they aren’t exposing any sensitive information. The signature is used for expiration and parameters that affect request/response headers. Without it, people would be able to temper with these parameters to their own will, and e.g. retrieve a supposed-to-be-expired file.

And X-Amz-Expires…what expires here? According to this a value of 900 is equal to 15 minutes, however I’ve been able to view this image hours later. Why would I want this?

That shouldn’t be possible, expiration is a very important S3 feature, it’s highly unlikely that it doesn’t work. Perhaps only if the objects you’re uploading have public-read ACL.

1 Like

I should clarify that the only way I’m able to retrieve an expired file is when it’s requested by my app. I was previously able to throw the url into an img src on any old html page and see my image, but not anymore. Doing that (and pasting the url into the browser address bar) now results in an access denied error and some xml that includes the expiration date. Shouldn’t my app be prevented from accessing the file as well? Or does it have special privileges because it’s the s3 account owner?

I just read this annnd it would appear that making a public upload is as easy as using the public: true argument.

Thank you so much for being receptive and helping noobs, btw. This gem rules and so do you.

1 Like

Yes, you will get that XML response when the presigned URL has expired. Note that it’s only the URL that can expire, not the object itself, so your app will always be able to access the file, as the AWS SDK internally uses a fresh URL.

1 Like