Skip to content

Add index.php to proxy opt out HTTP requests + fix regressions in curl support. #37

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

Merged
merged 12 commits into from
May 12, 2018

Conversation

diosmosis
Copy link
Member

@diosmosis diosmosis commented Apr 26, 2018

Changes:

  • Add matomo-proxy.php endpoint that only allows proxying the optout method.
  • Return correct value in handleHeaderLine() to avoid obscure curl error.
  • The curl HTTP header option requires an array not a string, so give it one.
  • Forward the Cookie header.
  • Tests for index.php.
  • Blurb in readme about proxying the opt-out form.

Tested w/ fopen & curl.

Fixes #29

Copy link
Collaborator

@Findus23 Findus23 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I tested it locally and everything works file.
I left two comments with minor nitpicks.

One more thing that might break (or I am misunderstanding something):
Let's say example.com gets tracked by matomo.example.
While normally the optout cookie is just set to matomo.example, with the proxy, the opt-out will be at example.com.
So will it then set the cookie to example.com?
If no, I guess it will fail as it tries to set a cookie to a foreign domain (I guess)
If yes, does Matomo know to handle the opt-out cookie if it is on another domain as itself?

I guess it should work, but I am not completely sure

proxy.php Outdated
'timeout' => $timeout
'timeout' => $timeout,

// 'ignore_errors' => true, // uncomment to debug error code responses
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that this is the wrong way around? If commenting is for debugging, it shouldn't be uncommitted by default.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s commented so developers don’t have to look it up next time when there is an error and zero output.

matomo-proxy.php Outdated
$allParams = $_GET + $_POST;

if (!in_array("{$allParams['module']}.{$allParams['action']}", $SUPPORTED_METHODS)) {
http_response_code(404);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After trying around a bit I couldn't find a way to circumvent this check.
But I noticed that a simple request to matomo-proxy.php causes an error (because module and action are not set), which is a bit ugly.

And the whole security depends on the order of $_GET + $_POST and the next person to edit this to know that php adds arrays from right to left overwriting POST by GET.

If someone switches this around accidentally, all Matomo modules can be accessed:

curl --data "module=CoreAdminHome&action=optOut" "http://localhost/tracker-proxy/matomo-proxy.php?module=Login&idSite=1&period=day&date=yesterday&action=

So I'd at least add a comment so it is clear that this is important. (at least for me it wasn't clear otherwise)

@diosmosis
Copy link
Member Author

Re cookies:

The proxy will just forward the set-cookie header, so the cookies will be associated w/ the tracker-proxy domain. So as long as tracking is done through the tracker-proxy domain, it will receive the ignore cookie. (Tested locally via /etc/hosts).

Also checked to see what will happen if the cookie_domain INI config option is set, and it doesn't apply to the ignore cookie (it's never created w/ a domain).

@diosmosis
Copy link
Member Author

Updated to check $_GET/$_POST w/o merging the arrays + check for absent module/action.

@level420
Copy link
Contributor

level420 commented May 2, 2018

@diosmosis @mattab see my comments in #29

There are 2 problems:

  • If the proxy is communicating with matomo instance which is secured (https://) from an unsecured site (http://), matomo tries to set the PIWIK_SESSID cookie for the secured site which is not available for the unsecured one. The iframe is displayed correctly, but clicking on the checkbox does not set the piwik_ignore cookie.

  • The opt-out iframe only works if it is able to set the PIWIK_SESSID cookie, which is in my case undesired as I'd like to work without any matomo cookies, besides of the piwik_ignore cookie.

  • Opt out should also be possible with a simple cookie piwik_ignore with value ignore or similar, so we wouldn't need any special value for the opt out to work. We could also ommit the complete opt out proxy as a simple php file is sufficient which sets or deletes the cookie for the current domain.

@diosmosis
Copy link
Member Author

Updated to support http proxy => https matomo.

@mattab
Copy link
Member

mattab commented May 3, 2018

Opt out should also be possible with a simple cookie piwik_ignore with value ignore or similar, so we wouldn't need any special value for the opt out to work. We could also ommit the complete opt out proxy as a simple php file is sufficient which sets or deletes the cookie for the current domain.

@level420 That's a good idea I think, but this would be a core change and improved in the opt-out iframe I believe. so maybe you can create an issue for this idea in https://github.com/matomo-org/matomo/issues ?

@diosmosis diosmosis added this to the Current sprint milestone May 3, 2018
proxy.php Outdated
@@ -11,6 +11,8 @@
exit; // this file is not supposed to be accessed directly
}

$DEBUG_PROXY = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be more like $NO_VERIFY_SSL or maybe better IGNORE_HTTP_ERRORS? or something? DEBUG_PROXY is good though as well and maybe best 👍 . Would maybe just explain what it does in a comment

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does a couple other things for debugging. I can split it into DEBUG_PROXY and NO_VERIFY_SSL (DEBUG_PROXY also removes error silencing so file_get_contents will spit out error messages).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 if splitted, it would actually allow someone to use it with a self signed certificate etc without silencing other errors 👍

@@ -260,6 +299,14 @@ function getHttpContentAndStatus($url, $timeout, $user_agent)
curl_setopt($ch, CURLOPT_POSTFIELDS, $stream_options['http']['content']);
}

if (isset($stream_options['ssl']['verify_peer']) && $stream_options['ssl']['verify_peer'] == false) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this the same as using DEBUG_PROXY in the if?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's done above, this translates the stream options to curl options.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I'm getting it. By the looks they are only set to false when using $DEBUG_PROXY = true correct? I'm thinking instead of translating it might be easier to read by using if($DEBUG_PROXY). May be also less fragile if eg for some reason the stream option changes it doesn't change the curl behaviour etc. But I didn't have a deep look I might be missing something.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing code follows the pattern of:

  1. set stream_options for file_get_contents
  2. if curl, transform already set stream options to curl options

The stream option name won't change, it's the actual php option name. It might change in a PHP version, but that's different than a developer deciding to rename it (which they can't do).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Opt-Out Cookie and forward Opt-Out iFrame
6 participants