Home > Mobile >  AWS: Why isn't my lambda function URL returning CORS headers for my preflight requests?
AWS: Why isn't my lambda function URL returning CORS headers for my preflight requests?

Time:09-17

I am playing around with lambda function URLs, which seem like a perfect fit for my use case.

I have a lambda configured with function URL turned on, Auth type of AWS_IAM, and CORS turned on with default settings (Allow Origin *, nothing else set). From Javascript running in Chrome I am sending a signed request to the lambda with code that looks like:

  const url = new URL(rawUrl)

  const signer = new SignatureV4({
    credentials: *******,
    sha256: Sha256,
    service: "lambda",
    region: region,
  })

  const request = new HttpRequest({
    hostname: url.hostname,
    path: url.pathname,
    body: JSON.stringify({}),
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      host: url.hostname,
    }
  })

  const send = async () => {
    const {headers, body, method} = await signer.sign(request)
    console.log('send.headers', headers)
    const result = await fetch(rawUrl, { headers, body, method })
      .then((res) => res.json())
    return result
  }

  send()
    .then((data) => {
      console.log('success', data)
    })
    .catch((reason) => {
      console.log('error', reason)
    })

When this code runs it generates a request that fails CORS because the preflight is not validated. The curl equivalents of the requests Chrome is sending are

curl 'https://**********.lambda-url.us-west-2.on.aws/' \
  -H 'sec-ch-ua: "Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'authorization: AWS4-HMAC-SHA256 Credential=*******/*******/us-west-2/lambda/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=***********' \
  -H 'Content-Type: application/json' \
  -H 'x-amz-content-sha256: ************' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36' \
  -H 'x-amz-security-token: ********' \
  -H 'Referer: http://localhost:3000/' \
  -H 'x-amz-date: 20220916T035331Z' \
  -H 'sec-ch-ua-platform: "macOS"' \
  --data-raw '{}' \
  --compressed

for the request and

curl 'https://*******.lambda-url.us-west-2.on.aws/' \
  -X 'OPTIONS' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-US,en;q=0.9' \
  -H 'Access-Control-Request-Headers: authorization,content-type,x-amz-content-sha256,x-amz-date,x-amz-security-token' \
  -H 'Access-Control-Request-Method: POST' \
  -H 'Connection: keep-alive' \
  -H 'Origin: http://localhost:3000' \
  -H 'Referer: http://localhost:3000/' \
  -H 'Sec-Fetch-Dest: empty' \
  -H 'Sec-Fetch-Mode: cors' \
  -H 'Sec-Fetch-Site: cross-site' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36' \
  -H 'dnt: 1' \
  -H 'sec-gpc: 1' \
  --compressed

for the preflight.

If I run that preflight in a terminal I get the following response:

HTTP/1.1 200 OK
Date: Xxx, xx Xxx 2022 xx:xx:xx GMT
Content-Type: application/json
Content-Length: 0
Connection: keep-alive
x-amzn-RequestId: xxxxxxxxx

Note that there aren't valid CORS headers being sent back, which results in Chrome not making the actual request. If I run the request itself in a terminal and bypass the preflight, then it runs successfully.

Is there an error in the way that I am making a request or how I've configured the lambda (I've tried various combinations)?

Thanks for your help!

CodePudding user response:

Not sure whether you were trying to edit an existing lambda, but I have observed, creating a new lambda function URL from scratch returns the expected headers in the OPTIONS response vs editing an existing one.

I am not certain what could be the reason for this behavior, but you may want to try creating a function URL from scratch, if you didn't do it already.

CodePudding user response:

Thanks to the comment from @jub0bs above I figured out the answer.

All the CORS configuration values default to being locked down. I had tried * for all the values, but did not set the Max age configuration value. With all setting properly filled out to the origins, methods, and headers that I am using AND Max age set to 0 everything started behaving itself.

  • Related