azure-functions-host: CORS broken for Linux consumption plans
I’m running a node Azure Functions app on a Linux consumption plan and since sometime over the weekend preflight requests have stopped reaching the corresponding HTTP triggers.
Investigative information
- Function App version (1.0 or 2.0): 2.0
- Invocation ID: I can’t provide invocation ID since I cannot see the request anywhere in the Azure Portal
- Region: West Europe
Repro steps
Make a preflight request to any HTTP trigger, presumably on a Linux consumption plan. As an example:
curl -i '<any-azure-function-http-trigger-url>' -X OPTIONS -H 'Connection: keep-alive' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' -H 'Origin: <any-origin>' -H 'Access-Control-Request-Method: GET' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36' -H 'Access-Control-Request-Headers: authorization' -H 'Accept: */*' -H 'Sec-Fetch-Site: cross-site' -H 'Sec-Fetch-Mode: cors' -H 'Referer: <any-referrer>' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9,sv;q=0.8,la;q=0.7' --compressed
Expected behavior
I expect the request to reach my HTTP trigger where I can process it.
Actual behavior
The request never reaches the HTTP trigger. I can’t see the request in any Azure Portal monitoring tools.
I get a response that looks like this:
HTTP/1.1 204 No Content
Server: Kestrel
Request-Context: appId=<app-id>
Date: Mon, 04 Nov 2019 10:46:27 GMT
Known workarounds
No known workarounds. Tried using proxies.json
to override headers, but the preflight request never reaches the proxies.
Related information
Removing any relevant preflight request header, such as Access-Control-Request-Method: GET
makes the request successfully reach the corresponding HTTP trigger.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 24 (8 by maintainers)
Definitely a bug in how we configured the CORS middleware. Opened a PR https://github.com/Azure/azure-functions-host/pull/5215 to fix this.
We should be able get this deployed sometime early next week.
@ericdrobinson @jacobgunnarsson Thanks for the patience and all the help investigating this.
thanks for all the details. investigating this more today and will update here soon.
Our functions are working again. Not sure if this is falling back to our own CORS implementation or being handled properly by the host (likely the host, at this point). One way or the other, browsers are no longer dropping the responses due to incorrect CORS responses.
@balag0 thanks for the update. it seems like I might be having some other issue then. It is letting OPTIONS requests through, yntil i set an
Origin
header, then I get “empty headers”Do I need to set anything but leaving all fields blank for CORS in the azure portal for it to work?
@balag0 Our functions still aren’t working properly. We’re about two weeks with broken features now. Is there a useful ETA for a fix deployment that you can share?
Update: The build with the fix is available now, the plan is to include this change with the next scheduled release starting end of the week instead of doing an one off deployment today.
A simple way to get a browser to trigger the Preflight Request is to issue a request (XHR; Fetch) that includes a payload (body). This example (adapted from MDN’s Fetch API documentation) should do the trick:
Hopefully this is helpful.
@ericdrobinson thanks for looking into this in a bit more detail!
@balag0 thanks for your reply! Yes, the issue still persists. As I wrote before adding allowed origins through Azure CLI (or through the portal) properly adds the
Access-Control-Allow-Origin
header to the preflight response.However, the issue is not wether or not the
Access-Control-Allow-Origin
header is present in the preflight response. The issue is that the rest of the required headers are missing, what aboutAccess-Control-Request-Method
orAccess-Control-Allow-Headers
? (or any of the otherAccess-Control-*
headers, described here)If the preflight request includes those headers but the response does not, the response is considered unsafe and is rejected by the browser.