matomo icon indicating copy to clipboard operation
matomo copied to clipboard

Piwik block by AdBlock even after renmaing piwik.php piwik.js

Open sambuev opened this issue 9 years ago • 68 comments

Hello, I have Piwik installed on my hosting with secret address: interes.site.com/sm/ and I have renamed piwik.php piwik.js to sm.php sm.js and I though it cannot by caught by AdBlock but unfortunately AdBlock on my Safari browser easily blocking Piwik and many other users with their Adblock (on Chrome, Firefox) out of my view :(

screen shot 2015-03-04 at 18 21 38

What can I do to avoid blocking Piwik? Is it possible to avoid it?

sambuev avatar Mar 04 '15 23:03 sambuev

I got this same error but I think this is difficulty for dev piwik

MESWEB avatar Sep 13 '15 11:09 MESWEB

I use rewriting and replace /piwik.php with juste /p. Works like a charm.

kylekatarnls avatar Sep 13 '15 12:09 kylekatarnls

Can You give any solution? I trying this but without success with uBlock - https://www.codelibrary.me/tag/ad-block/

MESWEB avatar Sep 13 '15 18:09 MESWEB

This is what I did (but with a proxy-pass in the same domain).

First remove "analytics" in the URL when you enter the rewrite rule and any word that can be seen as ads.

Then if it's not enough, use a proxypass (http://httpd.apache.org/docs/2.2/fr/mod/mod_proxy.html) on your own domain, so your URL to call Piwik will just look like "/p" and "/j"

(function() {
    _paq.push(['setTrackerUrl', '/p']);
    _paq.push(['setSiteId', 1]);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.type='text/javascript'; g.async=true; g.defer=true; g.src='/j'; s.parentNode.insertBefore(g,s);
  })();

kylekatarnls avatar Sep 15 '15 09:09 kylekatarnls

Guys, have you tried just replacing "piwik.php" and "piwik.js" in the tracking code with "js/", as described in https://github.com/piwik/piwik/blob/master/js/README.md? No .htaccess rewriting, file renaming, etc. needed.

See also: http://forum.piwik.org/read.php?2,83940,125929 http://forum.piwik.org/read.php?4,14971

I've been using that for years. Just make sure that the "piwik" string (or any other string blocked by the ABP) doesn't appear anywhere in the URL (i.e. domain name, directories). After coming across this issue report, I've just tried it again with ABP on Firefox and it doesn't block it. I checked the ABP "easyprivacy" list again, and it only checks for the "piwik" string anywhere in the URL.

P.S.: Another solution is in https://piwik.org/faq/how-to/#faq_132, but that would require the server being able to make outbound connections.

Joey3000 avatar Sep 15 '15 16:09 Joey3000

Non of all solution what You give not working with uBlock! I think the uBlock is hard to defeat. Only solution is use any server-side tracker. Piwik should use server-side tracking by default.

MESWEB avatar Sep 15 '15 20:09 MESWEB

@MESWEB From https://addons.mozilla.org/en-us/firefox/addon/ublock-origin/:

Out of the box, these lists of filters are loaded and enforced:

- EasyList
- Peter Lowe’s Ad server list
- EasyPrivacy
- Malware domains

Any chance your Piwik URL doesn't pass any of those?

Joey3000 avatar Sep 15 '15 21:09 Joey3000

There is following investigation necessary:

  • If the filter lists can include not just Piwik installation URL parts, but also URL parameters. (I tried the lists provided in the original issue post with ABP on Firefox and Piwik was not blocked. But I haven't checked if the "Peter Lowe’s Ad server list" also used by ublock includes URL parameters. Or if any other list could do that.)
  • If the ability by the plugin to check the parameters is browser dependent (e.g. due to some browser restrictions). Since the original issue post refers to Safari.

And if the block can be URL parameter based, it could be the time for a Piwik plugin where the user could freely change them. (I don't know how deep into the rabbit hole one would need to go to do that.)

Joey3000 avatar Sep 15 '15 22:09 Joey3000

@MESWEB Piwik was using server-side (it was called phpMyVisites), but for many reasons (performances, security) it has been switched to client-side and it's a good thing. I use proxypass + url-rewriting (it's exactly equivalent to the solution mentionned by @Joey3000, but it is faster because it does not use PHP) and uBlock does not block this solution.

kylekatarnls avatar Sep 22 '15 18:09 kylekatarnls

Yes I know it and I try changing url or filenames and dynamic changed filenames with .htaccess with RewriteRuele but without effect. I saw something strange - Any of my browser (Opera, Chrome, Waterfox) hasn't be counted by piwik but when Author of the PIWIK goes on my site I see his log in PIWIK. So my question is WTF? I'm not only one with this strange bug.

MESWEB avatar Sep 30 '15 15:09 MESWEB

Maybe you missclicked on uBlock and add a filter in your browser try to reset uBlock. Else, if all your stuff is on the same domain, it should not be blocked as uBlock does not search in the response body but only in request URLs.

kylekatarnls avatar Oct 05 '15 14:10 kylekatarnls

Ok so I was able to go around Opera's built-in adblocker with some major changes to PiWik. I'm still testing to see if it holds together after deploy. This was tested only on a local server and PiWik self-hosted:

  • Opera has an option to send "do no track" requests which are respected by PiWik. I did not find a workaround for that but I figure if the user goes that far I might as well respect that.

Changes I made to the PiWik installation files:

  • rename installation directory to p
  • p/piwik.js renamed to p.js
  • p/piwik.php renamed to p.php
  • main script array _paq renamed to yourArray. Not sure if this is necessary, try without this first
    • find _paq, replace with yourArray in p.js
  • find all occurrences of action_name in files under p/ (action_name is a request parameter, this was being picked up by the blocker)
    • replace ocurrences with yourParameter in:
      • p.js
      • core/Tracker/ActionPageview.php
      • core/Tracker/Request.php
      • js/piwik.js
      • js/piwik.min.js
      • vendor/piwik/piwik-php-tracker/PiwikTracker.php

Do all this at your own risk, this is totally experimental. This probably breaks something in PiWik. Not thoroughly tested.

bdore avatar May 22 '17 19:05 bdore

@bdore would be great to be able to do that trough a plugin

novakin avatar May 24 '17 19:05 novakin

Keep in mind, instead of renaming any files, you should also be able to create symlinks:

$ ln -s piwik.js p.js && ln -s piwik.php p.php

This is much cleaner and at least uBlock seems to allow these requests as far as I checked for now.

sboesch avatar Jun 19 '17 13:06 sboesch

A lot of things are wrong here !

EasyList contains these basic rules :

  • /piwik-$domain=~github.com|~piwik.org
  • /piwik.$script,domain=~piwik.org
  • /piwik.php /piwik/*$domain=~github.com|~piwik.org
  • /piwik1.
  • /piwik2.js
  • /piwik_
  • /piwikapi.js
  • /piwikC_
  • /piwikTracker.
  • .php?action_name=
  • .php?logRefer=
  • .php?logType=
  • .php?p=stats&
  • .php?ping=
  • .php?refcode=
  • .php?tracking=

Thus we have just to change in the tracking script

  • piwik.js to foo.js
  • piwik.php to foo

And a two URL rules in the webserver to map them to the original paths.

It will work until the parameter list doesn't contain evident keywords like stat, log, track ... Blockers can try to be clever, but they will never broke the www.

FabriceSalvaire avatar Jul 26 '17 11:07 FabriceSalvaire

If you use the "proxy" script to hide the real URL of your Piwik server (see https://github.com/piwik/tracker-proxy) you can also use that to hide parameter names as well.

When sending the JavaScript, just do a str_replace for "action_name=" to something else, e.g. "aname=" and then rename the $_GET parameter back to the original name. You should also rename this proxy script from "piwik.php" to something else.

So - first replace "action_name" in the provided JavaScript from the Piwik server:

        if ($piwikJs = $content) {
            echo str_replace('"action_name="', '"aname="', $piwikJs); 
        } else {

And this to accept "aname" as parameter but forward it as "action_name" in the server side CURL request to the Piwik server:

if(isset($_GET['aname']) {
        $_GET['action_name'] = $_GET['aname'];
        unset($_GET['aname']);
}
foreach ($_GET as $key => $value) {
    $url .= urlencode($key ). '=' . urlencode($value) . '&';
}

But be aware, that even the new parameter name "aname" may once get into filter lists as well - so you may have to use something else.

arnowelzel avatar Sep 12 '17 09:09 arnowelzel

@arnoweizel: where do place this code? In which file? I tried in piwik.php (from tracker-proxy), but no success, nothing is replaced, still have "action_name" thx for an advice in advance

omarr1000 avatar Oct 15 '17 10:10 omarr1000

@omarr1000: then you did something wrong. See the script here, which I use on my own server (https://arnowelzel.de):

https://arnowelzel.de/samples/piwik-tracker-proxy.txt

arnowelzel avatar Oct 15 '17 11:10 arnowelzel

thx! now I got it, did write the code at the wrong line )-;

omarr1000 avatar Oct 15 '17 13:10 omarr1000

I had to do 2 things: -First the symlinks $ ln -s piwik.js p.js && ln -s piwik.php p.php like proposed by @sboesch

  • Then modifiy piwik.js / piwik.php: piwik:js Rename "action_name=" to "_action_name" piwik.php Added in the first line of piwik.php: if(isset($_GET['_action_name'])) { $_GET['action_name'] = $_GET['_action_name']; }

ublocOrigin was blocking ?action_name=

londonuk371 avatar Nov 13 '17 13:11 londonuk371

Matomo tracking information should be obfuscated both to avoid being picked up by ad blockers but also for the security of the person being tracked! The current tracking URL is obnoxious with it's GET variables being sent over HTTP in plaintext.

Here's an example: https://domain/a.php?action_name=site&idsite=1&rec=1&r=058405&h=11&m=1&s=31&url=https%3A%2F%2Fdomain%2F&_id=9b550a96cfa8d490&_idts=1523890834&_idvc=1&_idn=0&_refts=0&_viewts=1523890834&send_image=1&pdf=1&qt=0&realp=0&wma=0&dir=0&fla=0&java=0&gears=0&ag=0&cookie=1&res=1920x1200&gt_ms=27&pv_id=Zf3r32

Matomo should generate a short random string and automatically create this .htaccess file if mod_rewrite is detected:

RewriteEngine On

RewriteRule ^a.js piwik.js [L,QSA]
RewriteRule ^a.php piwik.php [L,QSA]

and then when it provides you the code snippet should automatically have this url end point used.

Proposed Solution $_GET variables can be json encoded and then encrypted with a key generated for each matomo install. You provide the key to the js tracking file. JavaScript then instead provides the data like so: a.php?VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==

On the PHP side you would simply base64 decode then json_decode then just array_merge with $_GET.

hparadiz avatar Apr 16 '18 15:04 hparadiz

The key needs to be embedded in the JavaScript - otherwise it is not possible to encrypt anything on the client. So you don't gain any privacy, as anyone else could also send a request to the proxy script and find out, what key is used.

arnowelzel avatar Apr 16 '18 17:04 arnowelzel

I managed to unblock uBlock by creating the symlinks for `piwik.(js|php) and changing pwik.js

"action_name=

to

"a=b&action_name=

no need to rename variables @arnowelzel @bdore @londonuk371

select avatar Aug 22 '18 13:08 select

What also might work is creating a symlink like

mkdir foo
ln -s piwik.php foo/index.php

then point the tracking script to /foo, no need to mess with routes

select avatar Aug 22 '18 13:08 select

Do not use "piwik" as the folder name, rename it to something else. No need to rename the files or make rewrite rules. Just modify the tracking code and replace all entries of "piwik.php" and "piwik.js" with "js/". js/index.php will serve both php and js files for you.

isopetalous avatar Sep 06 '18 06:09 isopetalous

If you use the "proxy" script to hide the real URL of your Piwik server (see https://github.com/piwik/tracker-proxy) you can also use that to hide parameter names as well.

That's just a cool idea, thanks! It's even possible without creating a new URL, if you just use require('piwik.php') below setting the $_GET variable.

For those who are still searching, here are two PHP scripts to put in the piwik directory:

pi-js.php

<?php
$jsFile = file_get_contents('piwik.js');
echo strtr($jsFile, [
  '"action_name="' => '"myAC="',
  'piwik.php' => 'pi-php.php'  // Not sure, if this is really necessary
]);
?>

pi-php.php

<?php
if (isset($_GET['myAC'])) {
        $_GET['action_name'] = $_GET['myAC'];
        unset($_GET['myAC']);
}
require('piwik.php');
?>

Then just replace piwik.php in the Matomo code by pi-php.php and piwik.js by pi-js.php. No symlinks required, but you can use some to "hide" the name of the directory. This solution should even survive the next update of Matomo.

BurninLeo avatar Nov 13 '18 14:11 BurninLeo

This works for me :)

sed -i -e 's/action_name=/a=b\&action_name=/g' matomo.js
ln -s matomo.js m.js && ln -s matomo.php m.php
<script type="text/javascript">
  var _paq = window._paq || [];
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="//stats.domain.com/";
    _paq.push(['setTrackerUrl', u+'m.php']);
    _paq.push(['setSiteId', '1']);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'m.js'; s.parentNode.insertBefore(g,s);
  })();
</script>

Thanks @select & @sboesch

johackim avatar Apr 29 '19 20:04 johackim

I found that the easiest thing to do overall is make two tiny changes:

  1. Run sed -i -e 's/action_name=/a=b\&action_name=/g' matomo.js in the directory Matomo is installed in.
  2. Replace the g.src=u+'m.js' in the tracking code with g.src=u+'js/'.

That's it - now Matomo works, even if uBlock is installed.

w-biggs avatar Aug 08 '19 21:08 w-biggs

@ston3o @w-biggs

  1. chmod 444 matomo.js or chattr +i matomo.js

The Auto-Archiving cron runs periodically (either from your browser or via crontab depending on your config) and regenerates matomo.js, wiping out any changes you've made to it. The above should lock it down.

timbowhite avatar Aug 15 '19 22:08 timbowhite

regenerates matomo.js, wiping out any changes you've made to it. The above should lock it down.

To have your changes included in the regenerated matomo.js file, you can put the changes in the file matomo/js/piwik.min.js which is the "Source" file read to regenerate the minified file.

mattab avatar Aug 15 '19 22:08 mattab