Lambda function URL not respecting CORS settings

1

I am experimenting with using Lambda function URLs instead of API gateway. They seem to be working fine for the most part, except my browser keeps complaining about CORS. I did some testing. With CORS enabled on API gateway, I get this (expected) result.

$ curl -v https://lo1mb5fn4f.execute-api.ap-southeast-2.amazonaws.com/prod/default -X OPTIONS
*   Trying 52.62.9.26:443...
* Connected to lo1mb5fn4f.execute-api.ap-southeast-2.amazonaws.com (52.62.9.26) port 443 (#0)
* schannel: disabled automatic use of client certificate
* schannel: ALPN, offering http/1.1
* schannel: ALPN, server accepted to use http/1.1
> OPTIONS /prod/default HTTP/1.1
> Host: lo1mb5fn4f.execute-api.ap-southeast-2.amazonaws.com
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 27 Apr 2022 09:18:52 GMT
< Content-Type: application/json
< Content-Length: 0
< Connection: keep-alive
< x-amzn-RequestId: 2b81917b-42e6-47ac-88dd-4211fb0b93ad
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token
< x-amz-apigw-id: RO6ThFTYSwMFdqg=
< Access-Control-Allow-Methods: DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
<
* Connection #0 to host lo1mb5fn4f.execute-api.ap-southeast-2.amazonaws.com left intact

I then do the same query against the Lambda function URL also with CORS enabled in the console, however, I do not get the CORS headers returned.

$ curl -v https://b3cdmthu62o6bqzcrb7efnw7be0ktquf.lambda-url.ap-southeast-2.on.aws/ -X OPTIONS
*   Trying 54.66.8.158:443...
* Connected to b3cdmthu62o6bqzcrb7efnw7be0ktquf.lambda-url.ap-southeast-2.on.aws (54.66.8.158) port 443 (#0)
* schannel: disabled automatic use of client certificate
* schannel: ALPN, offering http/1.1
* schannel: ALPN, server accepted to use http/1.1
> OPTIONS / HTTP/1.1
> Host: b3cdmthu62o6bqzcrb7efnw7be0ktquf.lambda-url.ap-southeast-2.on.aws
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 27 Apr 2022 09:20:18 GMT
< Content-Type: application/json
< Content-Length: 20
< Connection: keep-alive
< x-amzn-RequestId: 13433ad6-7504-4054-abf5-ca53f9b39b3f
< X-Amzn-Trace-Id: root=1-62690ad2-0796999b639d9a5507c42dfb;sampled=0
<
"Hello from Lambda!"* Connection #0 to host b3cdmthu62o6bqzcrb7efnw7be0ktquf.lambda-url.ap-southeast-2.on.aws left intact

This does appear to be a bug in the way how Lambda reads the CORS data. I would appreciate any tips on what I might be doing wrong. If it is not me, is there a way to escalate this to AWS and report this as a bug?

profile picture
massyn
asked 2 years ago5032 views
2 Answers
0
Accepted Answer

Hey there,

When you send a preflight request using OPTIONS, you need to include the Origin that you're coming from, and which Request Method you're checking should be allowed. You can do this by including the Origin and Access-Control-Request-Method headers.

Try using the following curl command, which asks the Lambda Function URL whether it can make a cross origin request from http://example.com with a HTTP request method of DELETE

curl --location --request OPTIONS '<YOUR FURL HERE>' \
--header 'Origin: http://example.com' \
--header 'Access-Control-Request-Method: DELETE'
-v

The response I get from my test Function URL with the same CORS config that you've specified is:

> OPTIONS / HTTP/1.1
> Host: <My FURL>
> User-Agent: curl/7.64.1
> Accept: */*
> Origin: http://example.com
> Access-Control-Request-Method: DELETE
>
< HTTP/1.1 200 OK
< Date: Wed, 27 Apr 2022 14:50:31 GMT
< Content-Type: application/json
< Content-Length: 0
< Connection: keep-alive
< x-amzn-RequestId: fd7d31ab-604a-4cd0-9bae-ad9d83a74450
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: content-type,authorization,x-amz-date,x-api-key,x-amz-security-token
< Access-Control-Allow-Methods: GET,HEAD,POST,PUT,DELETE,PATCH

Let me know if this helps!

AWS
answered 2 years ago
  • By the way, if you're curious, Lambda implements the RFC according to the steps specified here: https://www.w3.org/TR/2020/SPSD-cors-20200602/#resource-preflight-requests

    The reason Lambda does not return CORS headers in your example request is because the Origin header was missing. In step 1, the specification says:

    If the Origin header is not present terminate this set of steps. The request is outside the scope of this specification.
    

    Since the Origin header is not present, we don't proceed to the following steps and just return a response.

0

Thank you for your feedback. After some more testing, I can confirm that the lack of Origin field in my api query was the root cause.

profile picture
massyn
answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions