CORS response headers not applied when request origin not in explicit origins list
See original GitHub issueDescribe the bug
Note: this was reproduced using an external auth service configuration (configured as an API gateway plugin). It’s unclear at this time whether it affects the default authservice functionality that ships with AES
When one specifies an explicit list of origin values in the ambassador Module’s cors
spec, and the preflight request’s Origin
is not in this whitelist, the preflight request is sent to the auth service first, then forwarded to the API service where it will likely fail as the API service expects Ambassador to handle CORS concerns.
I don’t believe it’s intended that preflight requests should ever be routed to an API service, as the edge stack should handle that for us. When the request’s origin is found in the whitelist, the preflight request is only sent to the auth service (as expected).
To Reproduce
- Deploy an external auth service to your cluster alongside ambassador.
- Ensure it can respond appropriately to CORS preflight OPTIONS requests (credentials will not be present)
- Configure ambassador to disable the default auth service.
- Configure ambassador to use the AuthService plugin instead and point it at your external auth service.
- Provide a basic
cors
config with an explicitorigins
list in theambassador
Module
cors:
origins: "https://www.google.com" # for example
methods: GET, POST, PUT, PATCH, OPTIONS, DELETE
headers: "*"
exposed_headers: "*"
max_age: "86400"
- Deploy a back end API service and an associated mapping
- Make a “non-simple” CORS request to your back end service
- Ensure that the request origin is not in the whitelist (i used chrome dev tools while on wikipedia’s home page)
- This is the simplest example to reproduce this behavior. You can achieve the same results even if you provide credentials on the request or modify the
cors:
spec to allow credentialed requests. See the attached document for a more complete listing.
fetch(
'https://*******.com/edge/echo/ping',
{
mode: 'cors',
method: 'POST',
body: "{}",
headers: {
'Content-Type': 'application/json',
}
}
)
- Observe:
- the preflight request is successfully handled by the auth service (returns 200)
- it’s likely that having the auth service return a 4XX here if it determines origin is not allowed will prevent the preflight request from being forwarded to the API service. However, it still seems like a bug to send preflight requests to the API service regardless of the auth result.
- the preflight request is forwarded to the API service (this is the unexpected part)
- the API service returns a 401
- the 401 behavior is somewhat particular to our setup, but I’m including it here for completeness and noting that this may also play a part in the preflight response not having any CORS response headers
- the preflight request is successfully handled by the auth service (returns 200)
Expected behavior
- [Most important] Ambassador should not forward the preflight request to the API service under any circumstances.
- Ambassador should apply the remaining appropriate CORS response headers to the preflight request, even if the origin is not whitelisted, possibly informed by the auth service. In this case, it perhaps it should be that the
Access-Control-Allow-Origin
header is not present or is the empty string. - Ambassador should respond with a 200 status code to the preflight OPTIONS request.
- There seems to be some wiggle room here in the CORS spec, so perhaps a 4XX is also acceptable. I believe browsers rely solely on the presence of the
Access-Control-Allow-*
headers to determine whether to deliver the response to the app or not and the status code is ignored.
- There seems to be some wiggle room here in the CORS spec, so perhaps a 4XX is also acceptable. I believe browsers rely solely on the presence of the
Versions (please complete the following information):
- Ambassador chart version: 6.5.9
- Kubernetes environment: Self-managed on AWS
- Ambassador version: 1.8.0
Additional context I don’t know if this is an Ambassador problem or an Envoy-proxy problem.
See the attached document for more details (and another type of CORS issue I have encountered) ambassador-cors-experiment.pdf
Issue Analytics
- State:
- Created 3 years ago
- Comments:5
Top GitHub Comments
We are experiencing the same issue in our product: we use external service to acknowledge API access and in case of 4xx errors client’s browser fails with CORS error in the console.
As a workaround we also keep CORS in two places now: CRD and auth-service code with CORS taken from application configuration.
We deploy to Openshift so at least we have single variable with the same CORS parameters which are injected both to CRD and auth-service, which seems at least minimizes the drawback of the workaround mentioned by @jcwilson.
Hoping to get it fixed soon anyway. Thank you.
keeping this one alive for now