Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pre-signing Amazon S3 urls for both head and get verbs

I'm hosting files on Amazon S3 that I want to make accessible using pre-signed urls.

For simple GET requests this works perfectly. There are some clients however that perform a HEAD request first (to retrieve the file size). Since the signature in the URL includes the http verb (GET vs HEAD), the head request fails.

The client simply does:

HEAD http://(bucketname).s3.amazonaws.com/filename?AWSAccessKeyId=(mykey)&Expires=(timestamp)&Signature=(sig)
GET http://(bucketname).s3.amazonaws.com/filename?AWSAccessKeyId=(mykey)&Expires=(timestamp)&Signature=(sig)

I cannot change the clients to use a different url for head and get. Is there a way to make amazon use a signature that accepts both HEAD and GET for the same resource?

like image 774
Ivo Jansch Avatar asked Mar 30 '13 10:03

Ivo Jansch


People also ask

How do I get pre-signed URL S3?

Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that contains the object that you want a presigned URL for. In the Objects list, select the object that you want to create a presigned URL for.

What is pre-signed URL in AWS S3?

A pre-signed URL allows you to grant temporary access to users who don't have permission to directly run AWS operations in your account. A pre-signed URL is signed with your credentials and can be used by any user.

Is S3 Presigned URL safe?

Pre-signed URLs can be generated for an S3 object, allowing anyone who has the URL to retrieve the S3 object with an HTTP request. Not only is this more secure due to the custom nature of the URL, but the available options also allow you to set an expiration on the URL, the default being one hour.

Why should you use S3 Presigned URLs?

Using presigned URLs to perform other S3 operations The main purpose of presigned URLs is to grant a user temporary access to an S3 object. However, presigned URLs can be used to grant permission to perform additional operations on S3 buckets and objects.


3 Answers

You can also simulate the HEAD behavior with GET if you specify Range header for first byte only. The difference will be that you receive 206 instead of 200 code. Secondly full size will be in Content-Range header.

curl -r 0-0 <URL>

like image 93
okrasz Avatar answered Oct 22 '22 14:10

okrasz


No. The HEAD and the GET need different signatures as there are subtle differences in the signature inputs.

Not sure what you're using to generate the pre-signed authentication URLs, but I know that some of the official AWS SDKs handle this, while others don't yet.

like image 44
Ryan Parman Avatar answered Oct 22 '22 13:10

Ryan Parman


with the help of a friend, I found a solution that works for me: proxy the HEAD request on my server, and redirect for the GET request.

When a request comes in with a HEAD verb to get the file info, I use my S3 code on my server to get the HEAD info and then I sent it back to the requestor myself.

When a request comes in with a GET verb to get the file itself, I do a 302 redirect with a pre-signed URL.

this works perfectly to handle both HEAD and GET by not needing to pre-sign both. I only pre-sign the GET request for the actual file.

like image 6
Derick Bailey Avatar answered Oct 22 '22 14:10

Derick Bailey