'AWS S3 Prevent Files From Being Download From Browser URL

I have an AWS S3 bucket, I want a majority of my files to be accessible via a url (my images and video links, etc) - This is already being accomplished. I have other files that I DO NOT want to have accessible from a URL, these would be audio files (mp3, wav, flac etc.). I only want users to be able to access my audio files by a php script serving them to the browser. More or less, I dont want user to have access to these files by guessing the URL of my AWS bucket where the files reside.

I'm stumped. Can anyone point me in the right direction. Thanks.



Solution 1:[1]

You can make the files private and generate signed URLs to allow someone temporary access to the files: Share an Object with Others

Or you can set a policy to restrict people from accessing the files directly, only allowing them to access a file if it was linked from your website: Restricting Access to a Specific HTTP Referrer

Or you can serve those files by sending them through your PHP script, i.e. download the file to your PHP server and returning the file contents from there. In which case you can just make those files private in S3 or even move them to a separate bucket that is completely private. I don't recommend this method because it puts more load on your server.

Solution 2:[2]

It sounds like an update to the bucket policy will help. Here is an example of allowing access that can be modified to deny access: http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html#example-bucket-policies-use-case-2.

Solution 3:[3]

You can structure your content under the bucket as:

  • public
  • private

and create a bucket policy similar to:

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

Change "bucketname" to your actual s3 bucket name.

Solution 4:[4]

Kinda old issue but after some research I found this response on another thread that could help for such trouble; the solution was to specify the content-type attribute inside the params object directly from your server-side code:

var params = { Bucket: 'your-bucket', Key: 'filename.png', ContentType: 'image/png', ... }

https://stackoverflow.com/a/60892449/12214978

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Rotenstein
Solution 2 Jeremiah Heller
Solution 3 Hesham Amin
Solution 4