Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
danielmarschall opened this issue Aug 17, 2023 · 9 comments
Assignees
Labels
help wanted Extra attention is needed

Comments

@danielmarschall
Copy link
Owner

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 <HTTP_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 <HTTP_ORIGIN> or absent if <HTTP_ORIGIN> 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
Copy link
Collaborator

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

  • .htaccess: This is dirty and not configurable well Header onsuccess unset Access-Control-Allow-Origin Header always set Access-Control-Allow-Origin "*"
  • ob_start() and emit output once after removing doublicate headers header_remove...
  • Use spatie once: You can wrapp everything that happens in the originHeaders() function into https://github.com/spatie/once. Here is an example how I use it in the webfat file:
      \frdl\booting\once(function() use(&$StubVM) {
      	if(!empty($StubVM->getFileAttachment(null, null, false))){
      		\spl_autoload_register([$StubVM,'Autoload'], true, true);
      	}
        });
      	
           $this->autoloadRemoteCodebase(true);
    
           \frdl\booting\once(function() use(&$StubRunner) {	
      	 $StubRunner->getStubVM()->_run_php_1( $StubRunner->getStubVM()->get_file($StubRunner->getStub(), '$STUB/bootstrap.php', 'stub bootstrap.php')); 
      	 $StubRunner->getStubVM()->_run_php_1( $StubRunner->getStubVM()->get_file($StubRunner->getStub(), '$HOME/detect.php', 'stub detect.php')); 
            });    


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
Copy link
Owner Author

danielmarschall commented Aug 17, 2023

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
Copy link
Collaborator

Maybe this works?

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

@wehowski
Copy link
Collaborator

Unfortunately ist does not help to remove the header first.

@wehowski
Copy link
Collaborator

wehowski commented Aug 18, 2023

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
Copy link
Owner Author

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
Copy link
Owner Author

danielmarschall commented Aug 18, 2023

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
Copy link
Collaborator

wehowski commented Aug 18, 2023

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
Copy link
Collaborator

wehowski commented Aug 18, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants