Middy: CORS uses 'headers.Origin' instead of 'headers.origin'

Created on 2 Dec 2018  路  4Comments  路  Source: middyjs/middy

I believe I found an issue in the CORS middleware when using multiple origin hostnames:

I have looked into it (code is here: https://github.com/middyjs/middy/blob/master/src/middlewares/cors.js#L11) and see that the middleware looks if handler.event.headers.Origin is in the list of origins in the options object. However, in my lambda I notice that the property name is actually origin - lowercase. The middleware then defaults the return value to the first value in the list - making it work at least half of the time ;)

This is the event I'm looking at in my lambda:

{
  "resource": "/<my-lambda-name>",
  "path": "/<my-lambda-name>",
  "httpMethod": "POST",
  "headers": {
    "accept": "application/json, text/plain, */*",
    "accept-encoding": "gzip, deflate, br",
    "accept-language": "en-US,en;q=0.9,nl;q=0.8,la;q=0.7",
    "cache-control": "no-cache",
    "content-type": "application/json;charset=UTF-8",
    "Host": "cvncasbjtj.execute-api.eu-central-1.amazonaws.com",
    "origin": "http://localhost:9000",
    "pragma": "no-cache",
    "referer": "http://localhost:9000/",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
    "X-Amzn-Trace-Id": "Root=1-5c0460a8-439ab6d017dfffc05eec1c90",
    "X-Forwarded-For": "<my-ip>",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },

  (...redacted for brevity...)

  "body": "<my request body>",
  "isBase64Encoded": false
}

Most helpful comment

It would be quite easy to come up with a fix for this problem within the CORS middleware itself. Is this something I can help with?

While I was writing the above, I was thinking that it would probably be better if it was possible to do some normalisation on the headers passed to the lambda function instead of normalising it case-by-case in the middlewares themselves. Turns out that already exists: https://github.com/middyjs/middy/blob/master/src/middlewares/httpHeaderNormalizer.js 馃憤
Adding this middleware before CORS solves my problem.

Perhaps a better idea then to suggest using these two middlewares together in the docs!

All 4 comments

It's likely API Gateway + HTTP2 related.

HTTP/2 encodes HTTP headers as lowercase. HTTP/1.1 headers were already case-insensitive, but not everbody adhered to that rule.

source: https://evertpot.com/http-2-finalized

The serverless framework is currently working through the same issue https://github.com/serverless/serverless/issues/2765

It would be quite easy to come up with a fix for this problem within the CORS middleware itself. Is this something I can help with?

While I was writing the above, I was thinking that it would probably be better if it was possible to do some normalisation on the headers passed to the lambda function instead of normalising it case-by-case in the middlewares themselves. Turns out that already exists: https://github.com/middyjs/middy/blob/master/src/middlewares/httpHeaderNormalizer.js 馃憤
Adding this middleware before CORS solves my problem.

Perhaps a better idea then to suggest using these two middlewares together in the docs!

I suggest using caseless to navigate properties in caseless way.

This line fails if event.headers contains 'content-type'.

https://github.com/middyjs/middy/blob/bd5fb453c3c6bacd416f84d8f0ae6add7d9972a2/src/middlewares/urlEncodeBodyParser.js#L13


This works regardless of cases.

const headers = caseless(event.headers)

if (headers.has['Content-Type']) {
  ...
}
Was this page helpful?
0 / 5 - 0 ratings