Consistency issue with the termination of OPTIONS requests
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Hi!
We have identified a consistency issue with the way the library terminate the OPTIONS requests, specifically when the `endPreflightRequests` option is activated which it is by default. Let me explain with a few cases:
Suppose an OPTIONS request sent to a server that has the library installed. The server uses the library as one of the middleware to handle the request.
If the request has no `origin`, despite the fact that it is uses the OPTIONS method, the [library will ignore the request](https://github.com/grantila/libcors/blob/master/lib/index.ts#L165) and let it continue its journey in the server. This makes sense regarding CORS as it is specifically made to handle cross-origin request and you mentioned it in the comment associated: No origin, no CORS to check.
You might have implemented some weird behavior that handle requests having the OPTIONS method later in the server (though that would probably be a bad idea) so it is not terminated.
Now suppose you send the same request but with all the proper headers, namely `origin`, `access-control-request-method`, `access-control-request-headers` and `access-control-allow-credentials`. Then the request is processed by the library, all the proper response-headers are added and it ends up being terminated by the `endPreflight()` method, resulting in a 204 HTTP status.
If you starts stripping non-mandatory headers, namely `access-control-request-headers` and `access-control-allow-credentials`, the behavior remains the same which make sense. You might not send credentials and you might not need custom headers either, though you still need CORS (for example with a cross-origin PUT method). Your request is still properly answered with a 204 HTTP status.
And even when the request is malformed, for example by sending unaccepted [headers](https://github.com/grantila/libcors/blob/0a8fed6156266f8cff052c14a65ba6f9156a8e0a/lib/index.ts#L225) or [method](https://github.com/grantila/libcors/blob/0a8fed6156266f8cff052c14a65ba6f9156a8e0a/lib/index.ts#L197), you will get a proper response with no CORS headers. It will terminate in a 204 HTTP status as the `endPreflight()` method is called.
However, supposed that you send a bad origin that do not match the origin that the server accept, in that case the library [simply terminate processing](https://github.com/grantila/libcors/blob/0a8fed6156266f8cff052c14a65ba6f9156a8e0a/lib/index.ts#L178) and [let the server continue the processing.](https://github.com/grantila/libcors/blob/0a8fed6156266f8cff052c14a65ba6f9156a8e0a/lib/index.ts#L298)
Shouldn't the request be terminated with the `endPreflight()` method as well so that it endsup with a 204 with no CORS header set as well? This would be much more logical regarding what the other use case do. Not doing so actually creates confusion as anyone sending an OPTIONS with a bad origin headers like `http://malicious-hacker.com` will still make the server process the request.
What do you think?
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in lib/index.ts at the linked handling around lines 165, 178, 197, 225, and 298, tracing how OPTIONS requests with missing, valid, malformed, and rejected origins are processed. Compare the rejected-origin path with endPreflight(), then define and test the consistent response behavior for a disallowed origin, including the expected status and CORS headers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100