Closed ramnivas closed 8 months ago
~CORS is only supposed to be used on cross-origin requests. You should avoid adding the Origin
header, either manually, or through using mode: "cors"
on your Fetch object.~
It might be enough to switch to Cors::default().block_on_origin_mismatch(false)
, but I think the most likely outcome of that is different CORS errors in your browser console relating to the lack of CORS response headers.
I am not adding the Origin
header (the only headers I add are accept: "application/json, multipart/mixed", content-type: "application/json"
.
Per https://fetch.spec.whatwg.org/#http-requests, the browser will add the Origin
header even when making a same-origin fetch unless it is a GET
or HEAD
request. In my case, it is a POST request, so per the spec, Origin
is added by the browser. That same spec states: "It cannot be reliably identified as participating in the CORS protocol as the Origin
header is also included for all requests whose method is neither GET
nor HEAD
".
It cannot be reliably identified as participating in the CORS protocol as the Origin header
You're right. I'd forgotten that detail.
Can you confirm whether Cors::default().block_on_origin_mismatch(false)
does or does not solve your issue?
There's a plan to make false
the default on the next release anyway. If it solves this I'll get a release cut today.
That partially works. I tested these scenarios:
However, when I combine 1 and 3, it doesn't.
As the context: here is how I set up CORS. For this experiment, I changed the None => Cors::default()
part to add .block_on_origin_mismatch(false)
.
I did more experiments, and here is what I observed:
OPTIONS
always precedes cross-domain POST
sPOST
s make it without a preflightOrigin
is sent in both scenarios (by the browser)This experiment suggests that CORS checking should not apply to methods other than GET
and HEAD
. Other methods will have a preflight request and checking that against CORS config should suffice.
I am less sure about POST
, however, because:
POST
will have Origin
sent (in fact, for all methods except GET and HEAD). So, the current logic of detecting CORS requests using the presence of Origin
will not work.POST
(in addition to GET and HEAD) is considered a "simple request" and thus may not be preceded by a preflight request (albeit with a host of other conditions that must be met).I've done some thorough testing of the scenarios presented and found that the behavior using Cors::default().block_on_origin_mismatch(false)
seems to be expected.
I used 2 local domains, foo.local & bar.local, both over HTTPS to eliminate browser quirks. On page load, 6 fetch requests were sent out:
All the POST requests had JSON body to remove possibility of request being considered simple.
All the same-origin requests responded 200 and were readable by the browser despite the lack of CORS response headers. All the cross-origin requests responded 200 but shows as rejected in the network tools since they also lacked the necessary headers.
All requests were sent with mode: 'cors'
and observed with Sec-Fetch-Mode: cors
request headers. Only the same-site GET requests were observed with missing Origin headers.
Conclusion: same-origin requests work as expected with Cors::default().block_on_origin_mismatch(false)
.
Reproduction repo can be produced on request.
Thank you so much for fixing this issue and doing the hard work of testing all possible scenarios. I will upgrade to the new version as soon as it is available.
On it (currently, upgrading to Rust 1.75, since that is a pre-requisite).
Upgraded and happy to report that everything is working as expected. Thank you!
Expected Behavior
I use
Cors::default()
in some instances. I expected this to be sufficient to make same-origin requests work, but I see the "Origin is not allowed to make this request" failures. I noticed that the browser doesn't make any pre-flight requests, and I see the failure when the browser makes a POST request.Current Behavior
The
POST
request fails with the "Origin is not allowed to make this request" message.Possible Solution
I am unsure, but should requests with
Sec-Fetch-Site: same-origin
be exempt from any CORS checking?Steps to Reproduce (for bugs)
The easiest reproduction will be with Exograph. Please let me know if you prefer a standalone example, which will be slightly more involved to set up.
Context
I am a developer for Exograph, where the same Actix server serves the API and playground. By default, it uses
Cors::default()
to configure CORS.Your Environment