Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access denied on S3 PUT request with pre-signed URL

I'm trying to upload a file directly to S3 bucket with pre-signed URL but getting AccessDenied (403 Forbidden) error on PUT request.

PUT request is allowed in bucket's CORS configuration.

Do I also need to update bucket policy with allowing s3:PutObject, s3:PutObjectAcl action?

P.S. Forgot to add. I already tried to add s3:PutObject and s3:PutObjectAcl with Principal: * and in this case uploading is working just fine, but how to restrict access for uploading? It's should be only available for pre-signed URL's, right?

like image 218
Scofield Avatar asked Jan 19 '18 12:01

Scofield


People also ask

Why is object URL Access Denied S3?

If you're trying to host a static website using Amazon S3, but you're getting an Access Denied error, check the following requirements: Objects in the bucket must be publicly accessible. S3 bucket policy must allow access to the s3:GetObject action. The AWS account that owns the bucket must also own the object.

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 S3?

A user who does not have AWS credentials or permission to access an S3 object can be granted temporary access by using a presigned URL. A presigned URL is generated by an AWS user who has access to the object. The generated URL is then given to the unauthorized user.

How do I upload a Presigned URL?

When you create a presigned URL, you must provide your security credentials and then specify a bucket name, an object key, an HTTP method (PUT for uploading objects), and an expiration date and time. The presigned URLs are valid only for the specified duration.


1 Answers

OK, I figured out how to fix it. Here are the steps:

  1. Replace Principal: * with "Principal": {"AWS":"arn:aws:iam::USER-ID:user/username"}. Instead of USER-ID:user/username put desirable user credentials which you can find in Amazon IAM section. Read more about Principal here: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html.
  2. Be sure that the user which you specified in Principal has s3:PutObject and s3:PutObjectAcl permissions for a needed bucket.
  3. Check your Lambda's function permissions. It also should have s3:PutObject, s3:PutObjectAcl for a needed bucket. You can check it on IAM Roles page (if you created separate role for a Lambda function) or through function Designer page (read only)

enter image description here

like image 101
Scofield Avatar answered Sep 20 '22 02:09

Scofield