AWS Cloudfront on Lambda Function via the Function URL url returning 403 Fobidden
Asked Answered
P

3

7

I have setup a lambda function url and cloudfront system

  1. Lambda Function Url is straight forward, a function that will return an image or a json value
  2. Cloudfront using this setting:
    • Origins:
      • Origin Domain: {LAMBDA FUNCTION URL}
      • Protocol: HTTPS only - TLSv1
      • Enable Origin Shield: No
    • Behavior:
      • Viewer: Redirect HTTP to HTTPS
      • Allowed HTTP Method: GET, HEAD
      • Restrict Viewer Access: No
      • Cache Policy: Managed-CachingDisabled
      • Origin request policy: AllViewer

The result however always return 403 Forbidden with this body

{ "Message": null }

And this header

X-cache: Error from cloudfront
x-amzn-ErrorType: AccessDeniedException

Is there any setting that I missed that cause this error? I already test direct hit using postman and browser to the function url an it works fine

Payable answered 15/8, 2022 at 11:18 Comment(0)
G
10

UPDATE - In your Origin Request Policy, set the new AllViewerExceptHost managed policy. That will forward all viewer headers except the Host header. Recommend you pair this with the CachingDisabled managed Cache Policy.


The issue could be that you are forwarding the Host header to your origin (Lambda Function URLs) via the AllViewer Origin Request Policy (ORP) that is attached to your cache behavior.

Why does this happen? You are using the AllViewer origin request policy, which forwards all HTTP request headers received from the viewer to your origin. So when CloudFront handles a request for d123.cloudfront.net—or even example.com as a configured CNAME—CloudFront will forward that value in the Host HTTP request header to your Lambda Function URLs origin. Because there is no function URL that resolves to that name, Lambda cannot find the function and returns a 403 Access Denied.

How to resolve: Instead of attaching the AllViewer origin request policy, create a custom origin request policy that forwards only the headers you need. Importantly, do not forward the Host header. Once this is configured, CloudFront will use your origin's hostname as the Host header—which Lambda will be able to resolve.

Gonorrhea answered 15/8, 2022 at 17:55 Comment(3)
Thank you, it works so well, for my case, I also need to also forward origin and user-agent but it is because of my lambda function code.Payable
Thank you for this questions + answer. I spent 3 days searching for a solution until I came across this article. I also had "AllViewer" policy. As soon as I updated to "AllViewerExceptHost" it worked immediately. Thank you!Degroot
This post explains this and other settings affecting Lambda URL invocation: dev.to/rimutaka/…Kassab
I
0

You will probably need to apply a resource based policy on the lambda function to allow cloudfront to invoke it. Go to the lambda function --> configuration --> permissions --> Resource based policy. Add a new permission specifying the arn of the cloudfront distribution and the Action of "lambda:InvokeFunction". Hope this helps?

Interfluve answered 15/8, 2022 at 12:23 Comment(0)
A
-1

Go to lambda function -> configuration -> Function URL -> Change Auth Type to None

Ambivalence answered 7/6, 2024 at 13:31 Comment(1)
You shouldn't just trade security for that, each specific use case demands a specific configuration, maybe you have WAF on your distribution to protect you against attacks like DDoS, allowing Public access to lambda function would kill that feature because now you can access the lambda function url directly.Commissar

© 2022 - 2025 — McMap. All rights reserved.