You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Response headers to pre-flight requests from some browsers when using javascript fetch() when Bearer authentication is used do not include CORS headers, causing some browsers (Chrome, Safari, Edge) to reject the response. Firefox does not seem to do a pre-flight check so it is not affected.
After starting the script, this works in a terminal:
# curl http://localhost:8080/secure/hello1 -H 'Authorization: Bearer super_secure_token_1'
OK
Chrome, Safari, Edge
Under
Chrome 113.0.5672.92 (Official Build) (arm64),
Safari 16.4 (18615.1.26.110.1), and
Edge 113.0.1774.35 (Official build) (arm64),
this does not work. The fetch to the secure page fails, and I see
Testing.
HELLO1
OK
In the developers' console in Chrome, I see
Access to fetch at 'http://localhost:8080/secure/hello1' from origin 'http://localhost:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
GET http://localhost:8080/secure/hello1 net::ERR_FAILED
Uncaught (in promise) TypeError: Failed to fetch
Under "Headers" for the pre-flight, I see:
So indeed, the headers don't seem to include Access-Control-Allow-Origin: * as I would expect, and as the request to /hello2 does.
Under Firefox 112.0.2 (64-bit) this works as expected.
When I load http://localhost:8081 in a browser, I expect to see
Testing.
OK
OK
The two fetch calls to the server at localhost:8080 should replace HELLO1 and HELLO2 with the secure content and the insecure content, respectively.
When I look at the RestRserve logs, it seems like Firefox does not make a pre-flight check; instead, it just sends over the request in a GET request with the token, and RestRserve obliges with a proper response with CORS headers:
{"timestamp":"2023-05-09 21:28:00.826798","level":"DEBUG","name":"Application","pid":65118,"msg":"","context":{"request_id":"fe17904c-eea7-11ed-8461-ae6922d47386","request":{"method":"GET","path":"/secure/hello1","parameters_query":{},"parameters_path":[],"headers":{"sec-fetch-site":"same-site","connection":"keep-alive","dnt":"1","origin":"http://localhost:8081","authorization":"Bearer super_secure_token_1","sec-fetch-dest":"empty","referer":"http://localhost:8081/","accept-encoding":["gzip","deflate","br"],"host":"localhost:8080","accept-language":["en-GB","en;q=0.5"],"sec-fetch-mode":"cors","accept":"*/*","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0"}}}}
{"timestamp":"2023-05-09 21:28:00.829188","level":"DEBUG","name":"Application","pid":65118,"msg":"","context":{"request_id":"fe17904c-eea7-11ed-8461-ae6922d47386","response":{"status_code":200,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.11","Access-Control-Allow-Origin":"*"}}}}
Environment information
> sessionInfo()
R version 4.2.1 (2022-06-23)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.3.1
Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_4.2.1 tools_4.2.1 renv_0.15.5
The text was updated successfully, but these errors were encountered:
On further exploration, this is what I think is happening:
Authentication middleware looks at the request, and since it doesn't have the authorization header in it (because it is a pre-flight request) it sets the status to 401 (when the token is parsed).
The CORS middleware will only add the headers if the status is <300, so it doesn't get any CORS headers (when the CORS middleware runs).
RestRserve sends the response to the pre-flight with 401 and no CORS headers.
In order to (temporarily?) work around this, I wrote a middleware to send 200 for specific OPTIONS requests:
handle_preflight_401_mw = Middleware$new(
process_response = function(request, response){
if(
request$method == 'OPTIONS' &&
'authorization' %in% request$headers[['access-control-request-headers']] &&
request$headers[['access-control-request-method']] == 'GET'
)
response$set_status_code(200)
},
id = "handle_preflight_401"
) # Put between CORS and auth middlewares
I think the thing with Firefox was a red herring: a CORS cache issue. At any rate, with the above middleware it seems to work in Chrome. If this is a bad idea, or there is some other solution, I'd love to know.
Thanks for reporting, looks like we need to update authorization middleware to not check authorization header for OPTIONS requests - https://stackoverflow.com/a/52072116/1069256
Describe the issue
Response headers to pre-flight requests from some browsers when using javascript
fetch()
when Bearer authentication is used do not include CORS headers, causing some browsers (Chrome, Safari, Edge) to reject the response. Firefox does not seem to do a pre-flight check so it is not affected.To Reproduce
The example below is adapted from the examples in the docs.
After starting the script, this works in a terminal:
Chrome, Safari, Edge
Under
this does not work. The
fetch
to the secure page fails, and I seeIn the developers' console in Chrome, I see
Under "Headers" for the pre-flight, I see:
So indeed, the headers don't seem to include
Access-Control-Allow-Origin: *
as I would expect, and as the request to/hello2
does.Looking at the RestRserve logs confirms this:
Expected behavior
Under Firefox 112.0.2 (64-bit) this works as expected.
When I load
http://localhost:8081
in a browser, I expect to seeThe two fetch calls to the server at
localhost:8080
should replaceHELLO1
andHELLO2
with the secure content and the insecure content, respectively.When I look at the RestRserve logs, it seems like Firefox does not make a pre-flight check; instead, it just sends over the request in a GET request with the token, and RestRserve obliges with a proper response with CORS headers:
Environment information
The text was updated successfully, but these errors were encountered: