0

I have setup CloudFront with S3 origin to serve images from S3. Now Adding Lamnda@Edge for image conversion. which works based on status code (200 or 404)

But Cloudfront event for origin-response always has status: '403'

Here is the sample response (from event.Records[0].cf)

{
    config: {
        distributionDomainName: 'xxxx.cloudfront.net',
        distributionId: 'xxxxx',
        eventType: 'origin-response',
        requestId: 'YVAViQDNbJcmgRlZFEWjxS2xF5balXwR-Kkv8PN4jXRO4hEPksOaJg=='
    },
    request: {
        clientIp: '81.403.0.141',
        headers: {
            referer: [Array],
            'x-forwarded-for': [Array],
            'user-agent': [Array],
            via: [Array],
            pragma: [Array],
            'accept-encoding': [Array],
            host: [Array],
            'cache-control': [Array]
        },
        method: 'GET',
        origin: {
            s3: [Object]
        },
        querystring: '',
        uri: '/images/product/photo/photocell_white.webp'
    },
    response: {
        headers: {
            'x-amz-request-id': [Array],
            'x-amz-id-2': [Array],
            date: [Array],
            server: [Array],
            'content-type': [Array],
            'transfer-encoding': [Array]
        },
        status: '403',
        statusDescription: 'Forbidden'
    }
} 

I have S3 bucket is publicly writable (I know its dangerous, but just to get this working).

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicAccess",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::stage.domain.com/*"
        }
    ]
}

In CloudFront

Origin Domain Name : stage.domain.com.s3.amazonaws.com
Origin Path : /assets
Origin ID : S3-stage.domain.com

What is wrong here

Lambda Function : https://pastebin.com/raw/FNd59Tvn

roy
  • 6,344
  • 24
  • 92
  • 174
  • Without lambda@edge, it works I guess? So you get 403 only when you use the lambda to modify Origin response? – Marcin Aug 20 '20 at 02:47
  • No, CloudFront origin-response event always has status: '403'. I don't think it has to anything with Lambda function. – roy Aug 20 '20 at 03:00
  • Can you confirm that the bucket is acctually publicly accessible, you use website-s3 endpoint in your custom origin in CF. Also can check if the files requests actually existed, you are their owner and they are not using kms encryption. – Marcin Aug 20 '20 at 03:04
  • Look at your code. Change `if (response.status === '404') {` to `if (response.status === '403') {` and see what happens. – Michael - sqlbot Aug 20 '20 at 08:58

1 Answers1

3

S3 returns 403 by design. s3 returns 403 when the access user does not have permissions to s3:ListBucket.

You can find out more here

You need to add this statement to your policy:

       {
            "Sid": "PublicListAccess",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::stage.domain.com"
        }

WARNING

Make sure you understand the consequence of giving the public the ability to list all objects in your s3 bucket.

dCrux
  • 121
  • 5
  • Amazon always yells and screams about giving access and to understand the consequences, yet they never explain it anywhere. What are the consequences of allowing people to access a bucket in which public files are stored? I don't understand how else they are supposed to access them.. It's a public facing website. They need to be able to get the files... am I missing something? – allthewayaround Jul 11 '21 at 14:03
  • @allthewayaround they yell and scream to make you think clearly about the permission that you're granting. There are many cases where you may want to allow the public to get an object that they already know the key of, but not get a list all objects. – jbg Jun 22 '23 at 02:50