Section 3.2.3 of the Fetch standard provides some guidance about how servers can/should handle preflight requests.

A successful HTTP response, i.e., one where the server developer intends to share it, to a CORS request can use any status, as long as it includes the headers stated above with values matching up with the request.

A successful HTTP response to a CORS-preflight request is similar, except it is restricted to an ok status, e.g., 200 or 204.

Any other kind of HTTP response is not successful and will either end up not being shared or fail the CORS-preflight request. Be aware that any work the server performs might nonetheless leak through side channels, such as timing. If server developers wish to denote this explicitly, the 403 status can be used, coupled with omitting the relevant headers.

(my emphasis)

However, the server isn't meant to carry out much "work" during preflight: the CORS middleware is typically "stacked on top" of other middleware and should handle and "terminate" a preflight request rather than pass it on to the next handler in the chain.

Therefore, I'm wondering whether timing-based side-channel attacks during preflight should really be a concern, and whether omitting all CORS response headers is really necessary to avoid such attacks...

  • What kind of information useful to an attacker could be gleaned from such a vector?
  • Does it simply depend on the implementation of the CORS middleware of interest?
  • Are there known cases of such attacks?

2 Answers 2


The third paragraph you quoted refers to both preflight and non-preflight CORS requests (thus "... end up not being shared [with the requesting script] or fail the CORS-preflight..."; the italicized part only makes sense for non-preflight requests, where either it was a simple request or the preflight already occurred).

Thus, while the HTTP OPTIONS request handler for preflights should generally involve very little logic, the GET/POST/PUT/PATCH/DELETE/etc. handlers for non-preflight requests very often do lots of work even if not returning a "successful" CORS response (one that will be shared with the requesting script) due to not returning the necessary headers. Indeed, the server might not even be CORS-aware, and end up processing the request as normal without even executing any logic to determine whether or not to attach CORS response headers (or which values to set for them).

To answer your actual question: unless the server is (mis)configured such that it does interesting operations on OPTIONS requests, or perhaps if the list of allowed origins/headers/methods/etc. is unknown and you want to try to find it via a string comparison timing attack (good luck...), no, timing attacks on preflight requests in particular likely don't matter. But that doesn't mean timing attacks on unsuccessful CORS requests can't still be very effective!

For a simple example of a timing attack leaking data through unsuccessful CORS requests, consider the following scenario. You, the attacker, want to know if Alice and I have been chatting on site C[hat] recently. Site C has a search function for chat messages, and this search function is not protected against CSRF (because it's not state-changing). However, the search function uses an index to quickly determine whether there are any messages that meet the search criteria, before extracting the actual message bodies to generate links and snippets for the response page. You control site E[vil], which my browser is visiting while logged into C, and thus you can make my browser execute scripts. C doesn't trust E, so CORS requests will fail. You can nonetheless have my browser initiate a CORS request from E to C, searching for e.g. messages from Alice in the last week. You then start a timer and, when the CORS callback/continuation executes, check the timer to see if the response took under perhaps 30ms (implies no messages found, with a margin for some network latency) or over 50ms (implies that the server found messages and generated a page of results). You can even try search queries that should definitely have, or not have, results, in order to determine the timing of each sort of query.

Either way, you can't actually see the search results (because the CORS request fails; your callback/continuation is in the error path) but you can tell whether any results exist and, by fine-tuning the search query, can potentially discover some details about them (like whether they contain a particular phrase, or narrow down what window they occurred in). As with all timing attacks, there'd be some noise in the results, but you can submit many requests to get averages. This would be all unbeknownst to me unless I was monitoring my network requests carefully.

  • Your answer helped clear some things up for me. Thanks!
    – jub0bs
    Commented Feb 9, 2023 at 5:39

Say the server-side validates request parameters in a certain order. Validation failures on the first parameter will happen in shorter time than validation failures on the last parameter. So the timing of the rejection message will convey information back to the attacker on how many leading parameters validated.

All timing attacks depend on implementation details.

  • What parameters are you referring to, though? In the case of a preflight request, there's nothing to validate other than the origin and the values in of the Access-Control-Request-Methods header and the Access-Control-Request-Headers header (if any).
    – jub0bs
    Commented Jan 9, 2023 at 16:54
  • @jub0bs: And you think that adversaries will follow the rules of not sending other headers or attached data?
    – Ben Voigt
    Commented Jan 9, 2023 at 16:59
  • Yes, I'm aware that attackers could forge malicious preflight requests. But why would it matter if they send additional stuff in a preflight request, since a CORS middleware only processes CORS headers (Origin, ACRM, and ACRH) and ignores the rest? How could attackers leverage the fact that the server is configured for CORS to leak valuable information?
    – jub0bs
    Commented Jan 9, 2023 at 17:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .