-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Problem
While adding Origin validation for CORS requests, we found out that our OPTIONS implementation does not actually handle pre-flight requests, at least not completely #2986 (comment).
This is how it works right now:
Successful request
$ curl -X OPTIONS "http://localhost:3000/projects" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type" \
-H "Origin: http://localhost" -iHTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Fri, 27 Oct 2023 19:05:19 GMT
Server: postgrest/11.2.0 (8c9213d)
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PATCH, PUT, OPTIONS, HEAD, POST
Access-Control-Allow-Headers: Authorization, Content-Type, Accept, Accept-Language, Content-Language
Access-Control-Max-Age: 86400The actual response is given by the wai-cors library. We can notice because our implementation does not return pre-flight headers, only Access-Control-Allow-Origin. In summary, our OPTIONS does nothing here, the library does the response.
Failing request
$ curl -X OPTIONS "http://localhost:3000/projects" \
-H "Access-Control-Request-Method: TRACE" \
-H "Access-Control-Request-Headers: Content-Type" \
-H "Origin: http://localhost" -iHTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Fri, 27 Oct 2023 19:16:15 GMT
Server: postgrest/11.2.0 (8c9213d)
Access-Control-Allow-Origin: *
Allow: OPTIONS,GET,HEAD,POST,PUT,PATCH,DELETEOnly when it fails, our OPTIONS implementation goes through and returns this info. This happens because we set the library to not respond with an error and let the request continue:
postgrest/src/PostgREST/Cors.hs
Line 37 in 5c9c7f4
| , Wai.corsIgnoreFailures = True |
This still fails the pre-flight (in Firefox and Chrome at least) because
Access-Control-Allow-Methods is not set (different from Allow which has no meaning in CORS pre-flight).
Solution
We have two options here:
- Let the library return the error which is a
400with a predefined message indicating the problem. - Implement our own, which would mean to verify if the
OPTIONSCORS request is pre-flight (with the required headers) and respond with a custom error indicating the problem.
Any of these would liberate the simple OPTIONS CORS request (not preflight) to work as we want. For instance, it could bring back the schema definition mentioned in #790.