danielmarschall / oidplus

OIDplus 2.0 - An OpenSource online Registration Authority for OIDs and other Object Types
https://www.oidplus.com
Apache License 2.0
10 stars 6 forks source link

CORS Header issue: Duplicate Access-Control headers in REST API "OPTIONS" method #22

Open danielmarschall opened 10 months ago

danielmarschall commented 10 months ago

One possible bug found in REST API:

OIDplusPagePublicRestApi::handle404() calls originHeaders().

If REST is called with the request method "OPTIONS", then restApiCall_OPTIONS() will additionally send some of these headers. (Note: At least for IIS, the software seems to swallow the "OPTIONS" method and not forward it to PHP. I wonder if any software forwards "OPTIONS" to PHP?!)

Here is the comparison of the contents:

Header originHeaders restApiCall_OPTIONS
Access-Control-Allow-Credentials true true
Access-Control-Allow-Origin or * otherwise *
Access-Control-Allow-Headers If-None-Match, X-Requested-With, Origin, X-Frdlweb-Bugs, Etag, X-Forgery-Protection-Token, X-CSRF-Token Keep-Alive,User-Agent,Authorization
X-Frame-Options ALLOW-FROM or absent if is not set
Access-Control-Expose-Headers Etag + X-CSRF-Token + All <headers_list()>
Vary Origin
Access-Control-Allow-Methods GET, PUT, POST, DELETE, PATCH, OPTIONS

We should remove all headers from OIDplusPagePublicRestApi::handle404() (except Access-Control-Allow-Methods) and instead merge them into originHeaders().

@wehowski Since there are some differences in the values and I don't have much knowledge about CORS, I ask you to take a look and help me with the fix (after all, you are the author of originHeaders()). Thank you very much.

wehowski commented 10 months ago

Hello Daniel, there are 2-3 possible solutions I used before in other projects for this kind of problem:

About to pass OPTION requests to PHP: I am not sure, I must re-look about it, maybe via server-configs or autoprepend file or php-servers/listeners (do not use the last one in production they say). I must read, learn and test it...

danielmarschall commented 10 months ago

Your solutions are rather complex. We don't need such a complexity. We just need one set of "good parameters", and put everything in originHeaders(). The real question is just what are the "good parameters"? I cannot tell.

wehowski commented 10 months ago

Maybe this works?

    header_remove("Access-Control-Allow-Origin");
    header("Access-Control-Allow-Origin: ".strip_tags(((isset($_SERVER['HTTP_ORIGIN'])) ? $_SERVER['HTTP_ORIGIN'] : "*")));
wehowski commented 10 months ago

Unfortunately ist does not help to remove the header first.

wehowski commented 10 months ago

Does it make sence to only use the access headers if POST/PUT/DELETE request? I believe the the Access-Control headers are used if POST with X-Requested-With-Header e.g. ? EDIT: But the test request is a GET request.

danielmarschall commented 10 months ago

I have no experience with CORS, so I leave the decision to you.

I would like that the whole CORS stuff is located in one single method and that this method is only called once.

I need to have a set of good values (see my table above), and these set of values should be in that method.

And then, I will make sure that this method is only called once (I will take care of it)

I also need your reproduction in re #21 so that we can find out why your have duplicate headers and I not. Please quickly add a test debug output to the CORS output methods to check if they are indeed called twice.

danielmarschall commented 10 months ago

I simplify my question: What values do we need for Access-Control-Allow-Origin and what values do we need for Access-Control-Allow-Headers?

This page https://stackoverflow.com/questions/12630231/how-do-cors-and-access-control-allow-headers-work recommends to set Access-Control-Allow-Headers: Origin, Content-Type, Accept which does not match what we currently have.

I am very confused about all these paramters, and I need your help. At the moment your replies didn't help me unfortunately...

wehowski commented 10 months ago

Ok, sorry! I am preparing a page with tests for the use case with a reproduction of the error and demos.

The js-console printed out that the header is dublicate, although if the function might work if called only once, my settings don't look correct!

I will notify you in the evening when my tests and reports are complete.

wehowski commented 10 months ago

Hallo Daniel, Please excuse the inconvenience, again my Proxy is the culprit! This is the page to reproduce the error: https://frdlweb.de/api/rdap/whois-test

Access to XMLHttpRequest at 'https://webfan.de/apps/registry/plugins/viathinksoft/publicPages/100_whois/whois/webwhois_original.php?query=weid%3AEXAMPLE-3$format=json' from origin 'https://frdlweb.de' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'https://frdlweb.de, https://frdlweb.de', but only one is allowed.

OK 200: https://registry.frdl.de/plugins/viathinksoft/publicPages/100_whois/whois/webwhois_original.php?query=weid%3AEXAMPLE-3$format=json