2 min read

Protecting images on Amazon S3 through Rails app

Protecting images on Amazon S3 through Rails app


Amazon S3 allows users to store their objects in buckets. All buckets and their objects are associated with Amazon ACLs(Access Control Policies). ACL is a set of permissions of read, write and update on bucket and its objects..


In this approach, we see how to set permissions to S3 objects using appropriate Amazon’s ACL and allow a time-limited access to a protected object by using a  “pre-signed” request to prevent its reuse.


Amazon S3 allows to construct query strings for requests to access private Amazon S3 data. It allows us to retrieve a "pre-signed" request encoded as a URL and limits it by an expiration_time, which means the request data will not be accessible after a limited time.


The required authentication elements are specified as query string parameters namely AWSAccessKeyId, Expires and Signature


Following is an example query string authenticated Amazon S3 REST request:


GET /photos/image.jpg
?AWSAccessKeyId=GHQWRTWEUIQB7ISAMPLE&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D HTTP/1.1
Host: test.s3.amazonaws.com
Date: Mon, 10 Dec 2012 18:36:56 +0000


See Amazon S3 documentation, under section "Query String Request Authentication Alternative" for more details on it.


If you need to upload and protect your images in your Rails app to Amazon S3, you can use aws-s3 gem.


aws-s3 gem for Rails has a method ‘store’ in class AWS::S3::S3Object which is used to upload an object to a bucket as follows: 


AWS::S3::S3Object.store(


           base_name,


           File.open(local_file),


           bucket,


           :content_type => mime_type,


           :access => :authenticated_read


         )


You can set access to your bucket using Amazon's ACLs or bucket policy. Amazon accepts the following ACLs:


  • :private
  • :public_read
  • :public_read_write
  • :authenticated_read
  • :bucket_owner_read
  • :bucket_owner_full_control


Here we’ve used a authenticated_read bucket access policy which means only authenticated Amazon’s S3 users can see the S3 objects.


The library also has a method url_for in class AWS::S3::S3Object


which generates the said authenticated url (described above) for an object as follows:


S3Object.url_for('image.jpg', bucket)


By default, authenticated urls expire after 5 minutes from the time they were generated. Expiration options can be specified with expires_in options:


 # (Expires in 3 hours)
  S3Object.url_for('image.jpg',
                   bucket  ,expires_in => 60 * 60 * 3)


You can specify whether the url should go over SSL with the :use_ssl option:


# Url will use https protocol
  S3Object.url_for('image.jpg',
                   bucket,    use_ssl => true)


Using this approach, the S3 data is protected using appropriate access control policy and the end-users can access your data on S3 with the help of Amazon S3 REST request which is query string authenticated. It is further limited  with short timeouts after which the data becomes inaccessible which adds to security of your data on S3.


References:


Amazon S3 documentation


Ruby Library for Amazon's Simple Storage Service's (S3) REST API


Exciting Announcements at WWDC 2012: New MacBook Pro, Mountain Lion, and iOS 6

Exciting Announcements at WWDC 2012: New MacBook Pro, Mountain Lion, and iOS 6

The cat is finally out of the bag. Apple announced some amazing new hardware and software at the WWDC 2012 keynote. There were some expected...

Read More

How Businesses can Use Twitter 

Have you ever noticed just how many businesses and brands are starting to pop up on the various different social media platforms and want to know if...

Read More

How Golang is thriving in the software industry

Choosing the right programming language is the most crucial thing for the developers in today’s time. You need to choose a language which is robust...

Read More