Home > OS >  How to serve S3 object only in my website
How to serve S3 object only in my website

Time:02-26

I have a Laravel app which uses S3 storage for profile pictures but also for sensitive content like contracts. If I serve an image for example, I get this URL: "bucket_name".s3."region".scw.cloud/"Content".

I'd like to get the content of this URL only if the user is on my website. Because for now if I copy/paste the address everybody can access to it.

Thanks for your help

CodePudding user response:

You can make access to the objects in your bucket conditional upon the presence of the HTTP referrer header. Here is an example of an S3 bucket policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::mybucket/*"
            ],
            "Effect": "Allow",
            "Condition": {
                "StringLike": {
                    "aws:Referer": [
                        "http://www.example.com/*",
                        "http://example.com/*"
                    ]
                }
            }
        }
    ]
}

Just be aware that:

  1. HTTP headers can be spoofed
  2. referrer header is optional, so not all legitimate clients will present it

CodePudding user response:

There are multiple ways of handling this, depending on how secure you want to have things:

  1. As @jarmod suggested, you can set up a referer header filter. This works but can be faked if you have a determined hacker.
  2. You can create a presigned URL for the document. This allows access for an amount of time you decide. So, for example, if you only wanted a URL that is valid for 3 minutes you could generate it and send it on. Even if someone were to get a hold of that URL it has a limited lifetime that it is valid.
  3. Your Laravel application could act as a proxy for the S3 content. Your S3 bucket would be private and your application would have permission to read from the bucket. When a request came in for the file it would go to your application and the application would read the file from S3 and pass it on to the end user. In this way, you're positive that your user is logged in and able to access the file. However, this may take a bit more time as now you need to read from S3 (though you may be able to implement some caching) and then write the file to the end user.
  • Related