How to load a website via s3 with pre-signed URL - amazon-web-services

I would like to block public access to my webapp served via S3 and only allow pre-signed URL to load the website. To do this I have allowed static site hosting in S3, and allowed public read to all objects. This allowed me to load the website public. Then I added a policy to deny access to index.html:
{
"Version": "2008-10-17",
"Id": "PolicyForPublicWebsiteContent",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::web-portal/*"
},
{
"Sid": "PrivateReadGetObject",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::web-portal/index.html"
}
]
}
Thereafter I generated a pre-signed URL to the index.html page via using the sdk.
const url = s3.getSignedUrl('getObject', {
Bucket: 'web-portal',
Key: 'index.html',
Expires: signedUrlExpireSeconds
})
However, I get access denied when I try to access the URL provided via the SDK.
I assume this happens as I added the deny policy to index.html. I would be much obliged to know what is the proper way to implement such a feature with aws s3.

This was resolved by only adding the policy to allow other files (js, css) to be accessed publicly, and not adding any policy (Allow/Deny) to the index.html.
For me all my other files we located under the folder called static. Therefore I added a policy to allow public access to this folder.
{
"Version": "2008-10-17",
"Id": "PolicyForPublicWebsiteContent",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::web-portal/static/*"
}
]
}
After adding the above policy you cannot access the index.html page via browser. However you can access the index.html if you have a pre-signed URL. As the other required files are in public domain, the index.html was able to load the rest.
I pressume the same can be done if we can gzip the entier website. Thus all files will reside in one single zip folder. Then provide a pre-signed url to that file. In this way we do not have to enter any bucket policies for other non index files.

Related

Cannot access S3 object even though all indications are that I should including policy simulator. Why?

I can use this policy to upload files to my bucket from user A, in group Z. A different user in group B also is in group Z and therefore has the same policy. However, I cannot read the file when logged in as B to the AWS management console. I'm especially mystified because according to the Policy Simulator, this policy (plus the Admin access user B has) should fully enable B to see the file in question.
Instead, user B only gets Access Denied.
Help? I feel like I'm missing something very simple here.
My complete (if redacted) group policy is:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::my-bucket/*",
"arn:aws:s3:::my-bucket"
]
}
]
}
My auto-generated bucket policy is:
{
"Version": "2012-10-17",
"Id": "S3-Console-Auto-Gen-Policy-1645709424074",
"Statement": [
{
"Sid": "S3PolicyStmt-DO-NOT-MODIFY-1645709423946",
"Effect": "Allow",
"Principal": {
"Service": "logging.s3.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
My bucket has Block Public Access turned on.
The problem here is that even though you are logged into the AWS console, your authentication does not extend to downloading an S3 object via a simple HTTP GET of the object at https://mybucket.s3.region.amazonaws.com/myfile.png, as would happen if you pasted that URL into a new tab.
Instead, you can generate and use an S3 pre-signed URL to download the object. A pre-signed URL is time-limited and is signed with your secret key so it includes all the auth needed to download the object.
You can use the S3 console, awscli, or any AWS SDK to generate a pre-signed S3 URL, for example:
aws s3 presign s3://mybucket/myfile.png
Note that pre-signed URLs behave somewhat like a bearer token. Whoever has the pre-signed URL can use it to download the object, until it expires.
You can also download individual objects, or even entire buckets of objects, using the awscli (with appropriate authentication).

How to make a public bucket only accessible from cloudfront without OAI?

I have a bucket that contains some images. The bucket is publicly accessible using the following policy.
{
"Version": "2008-10-17",
"Id": "s3BucketPolicy",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::Bucketname/*"
}
]
}
Also I have a cloudfront distribution that points to the same bucket. My problem now is that my file is accessible from both cloudfront link and bucket link.
CloudfrontLink: www.xxxxxx.xxxx/xxxx
BucketLink: www.bucketname/xxx
My question how can i make my bucket publicly accessible using cloudfront only. I don't want signed urls or cookies. I want any my anyone with cloudfrontlink to be able to access the image and prevent anyone with bucketlink from accessing the image.
Change the S3 bucket policy principal to the OAI of the CloudFront Distribution. For example:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ABCDABCDABCDAB"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
This will prevent access to the bucket contents outside of CloudFront. You don't need signed URLS here. See the documentation for more details.

How to download aws s3 files from client side without IAM, but only IP restriction?

I'm new to s3 and here's what I got:
I have the URL of s3 some files in my db and I want to download them in my client app with that URL (e.g. https://my_s3_bucket_name.s3.amazonaws.com/sample_2-1591371022041.pdf).
I don't want to make it public to everyone but I don't want to make it available to only my IAM. Instead, I want to open to public to my client side web app url. i.e the file should only downloadable when the url is called from from http://my_client_app.com
I took reference form this and made a public policy for my public ip (and the ip address of where I host http://my_client_app.com) but it doesn't seems working, when I open the File URL from my browser I still get 403 forbidden.
my bucket policy:
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my_bucket_name_hellobucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"my_public_ip/24",
"my_aws_ec2_ip/24"
]
}
}
}
]
}
ps1: if I set read access to public, i'm able to download the file with the file URL
ps2: can anyone tell me what the "Id" means / when will it be used in the bucket policy?
Thanks!
Based on OP's feedback in the comment, setting "Principal": "*" should allow anonymous access.

Static web hosting on AWS S3 giving me "403 permission denied"

I will appreciate if anyone can point me out where I'm doing wrong. see below steps
I have a domain name in route53.
Based on the domain name, I have created a bucket name ( for sake of my question lets stick to bucket and domain name as abc.nl)
Created the bucket, without changing any default provided check-list.
Clicked the bucket(abc.nl) and added below "bucket policy"
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567:user/usrname"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::abc.nl/*"
}
]
}
I have provided my username policy of AmazonS3FullAccess in IAM.
My Block public access (account settings) also unchanged.
Now I uploaded my all static files to the bucket(abc.nl).
In properties tab, I have added index.html under static website hosting block.
Now, as per the manual, I should able to click the link and access the page.
But for some reason, it's throwing me 403 access forbidden error.
In my understanding, by simply adding bucket policy you turn on public access. But for me, I don't see "public" tag. So, don't know what's going on. (My understanding could be wrong, hence this post.)
In case you are wondering which manual, I'm following, https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.htmlhow to host static web site.
Anyway, anyone points me out, where I'm doing wrong and which options should I choose from the permissions for the bucket? I could be missing out some lines.
PS: I have created and deleted the same bucket multiple times, just to start fresh every time.
The Principal value of your bucket policy is wrong. Copied from the Example: Setting up a Static Website Using a Custom Domain that you have linked to:
To grant public read access, attach the following bucket policy to the example.com bucket, substituting the name of your bucket for example.com.
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"PublicReadGetObject",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::example.com/*"]
}]
}
To make the bucket public (= everyone), you need to set * as principal in your bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::abc.nl/*"
}
]
}
Please also check that you don't have Block public access settings on the bucket because it will prevent you from making the bucket public.
Follow the below Steps 100% working.
Under Buckets, choose the name of your bucket.
Choose Permissions.
Under Bucket Policy, choose Edit.
To grant public read access to your website, copy the following bucket policy, and paste it into the Bucket policy editor.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::**YOUR-BUCKET-NAME**/*"
]
}
]
}
NOTE: AWS documentation Link
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::pasteyourbucketname(copy&pasteARNName)/*"
}
]
}

[AWS]s3 bucket web hosting not working

I'm googling since several hour without solution.
I'm trying to manage my bucket as web directory but it's not working fine.
Here is my bucket policy :
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my_bucket/*"
}
]
}
I have an index html file at top level of the bucket, and a directory.
I can access the index file like this :
https://s3-eu-west-1.amazonaws.com/my_bucket/my_index_file.html
But all the following request give an xml access access denied error
https://s3-eu-west-1.amazonaws.com/my_bucket/
https://s3-eu-west-1.amazonaws.com/my_bucket
https://s3-eu-west-1.amazonaws.com/my_bucket/my_folder
https://s3-eu-west-1.amazonaws.com/my_bucket/my_folder/my_sub_folder
I haven't found a solution. Please let me konow if someone know how to achieve this, so that I can browse my bucket through firefox or another browser.
Thanks
If you want to make the static website hosting with the necessary index.html & default pages - you need to enable S3 Static Website Hosting. Just making the files / S3 objects public wouldn't help the index.html routing.
Once you do that you would get URLs like - http://examplebucket.s3-website-us-east-1.amazonaws.com/
Checkout the following links
http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html
http://docs.aws.amazon.com/gettingstarted/latest/swh/website-hosting-intro.html
You have to create 2 buckets, one for example.com and one for www.example.com
Set bucket policy for both like below:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example.com/"
}
]
}
Follow this link : https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html