@Zozman opened this Issue on April 18th 2022

According to the documentation in the Matomo FAQ, CORS settings can be set by setting the cors_domains array in the config.ini.php to only allow certain domains to interact. However even if this is set, when sending a POST request to the matomo.php endpoint with a domain in the Origin request header that is not on the list still returns a 204 instead of an error.

Expected Behavior

When the Origin request header is set to a URL not on the list, the response should be some sort of 4xx response.

Current Behavior

Response is a 204

Possible Solution

Set behavior to return a 401 in this instance

Steps to Reproduce (for Bugs)

  1. Set a value in cors_domains in the config.ini.php to your domain.
  2. Verify these values on the System -> General Settings page under the Cross-Origin Resource Sharing (CORS) domains section.
  3. Send a POST request to the /matomo.php endpoint with the Origin header set to a value not in the cors_domains array (for example, https://evil.site
  4. Observe response is 204.

Context

This bug could allow malicious actors to hit endpoints from environments outside the allowed websites.

Your Environment

  • Matomo Version: 4.9.0
  • PHP Version: 8.0.17
  • Server Operating System: Linux (using Matomo docker container 4.0.9-apache)
  • Additionally installed plugins: None
  • Browser: Observed in Chrome 100.0.4896.127 and using Postman
  • Operating System: Mac OS X
@peterhashair commented on April 19th 2022 Contributor

@Zozman thanks for the bug report, I think that's a bug I made in this PR, https://github.com/matomo-org/matomo/pull/19030.

Here should be instead of *, I believe should be a combination of cors_domains and sites domains in the database. ping @sgiehl

https://github.com/matomo-org/matomo/blob/dc753b2fc6e691d0830ec03143ae06c091474296/core/Tracker.php#L119

@peterhashair commented on June 6th 2022 Contributor

should we assign this issue to the 5.0 milestone, since it's breaking changes?

@tsteur commented on June 9th 2022 Member

I'm not sure. Thinking of tracking I'm wondering if 204 is maybe actually the correct response since the tracking request was processed and we would want to avoid that because of https://github.com/matomo-org/matomo/blob/4.10.1/js/piwik.js#L2843-L2850 we would retry that tracking request.

A 204 would describe exactly above. Request was executed but no response/content.

AFAIK when sending a tracking request and there is a CORS error then the request itself was still executed. It's only that the response wasn't readable for the client. So we'd want to make sure to not send every tracking request twice.

@sgiehl commented on June 9th 2022 Member

I guess that depends on the expectation. I would actually also assume that a configured cors domain would also disallow requests coming from other origins. In that case it would be correct to send a 403 Forbidden. We then would need to handle the 403 in another way in tracking js for sure.

@tsteur commented on June 9th 2022 Member

You can see this in the examples on https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS as well that these send HTTP 2XX (200 and 204) headers. And the browsers decided if the client can read the response.

Also

CORS failures result in errors but for security reasons, specifics about the error are not available to JavaScript. All the code knows is that an error occurred. The only way to determine what specifically went wrong is to look at the browser's console for details.

image

The browser console already shows correctly when a CORS error happens

image
Powered by GitHub Issue Mirror