@negreanucalin opened this Issue on October 2nd 2019

A given: The intention of using Matomo to "track" user actions is strictly to see how users interact with a given page and provide enhancements but an ad-blocking software can be an impediment

Problem: Maybe another good way to spoof an ad blocker like uBlock Origin (v 1.22.4) would be to encode/encrypt each tracked event.
This software (and many other I recon) checks url parameters and blocks calls :
image
It also checks script names, ex:"tracking.js", "matomo.*" etc are nnot loaded

Idea: For each site optimally generate a token (included in the generated js block) and encode the url string, or a base64 encode or Hex encode.
Basically to have multiple options on how the url string should be encoded/decoded

EX (base64):
From &idsite=1&rec=1&r=502660&h=10&m=23&s=3&url=
To Jmlkc2l0ZT0xJnJlYz0xJnI9NTAyNjYwJmg9MTAmbT0yMyZzPTMmdXJsPQ==

EX (Hex):
From &idsite=1&rec=1&r=502660&h=10&m=23&s=3&url=
To 266964736974653d31267265633d3126723d35303236363026683d3130266d3d323326733d332675726c3d

Solution: Multiple pre-defined custom handlings using setCustomRequestProcessing ?

This way if a developer wants to really spoof the ad-blocker, he can use his site as a reverse proxy with this encoding feature and the ad-blocker wouldn't know the difference between a tracking and a usual call.

Current workaround
P.S: Does not track the user's IP since Curl does not allow to set REMOTE_ADDR
Front-end:

<script type="text/javascript">
    var _paq = window._paq || [];
    _paq.push(['setCustomRequestProcessing', (params) => {
        $.ajax({
            type: "POST",
            url: "<?php echo $_SERVER['TRACKING_URL'];?>encoded/",
            data: {action: btoa(params)}
        });
    }]);
    /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
    _paq.push(['setUserId', USER_NAME]);
    _paq.push(['trackPageView']);
    _paq.push(['enableLinkTracking']);
    (function() {
        _paq.push(['setSiteId', "<?php echo $_SERVER['TRACKING_SITE_ID'];?>"]);
        var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
        g.type='text/javascript'; g.async=true; g.defer=true; g.src="<?php echo $_SERVER['TRACKING_URL'];?>js/"; s.parentNode.insertBefore(g,s); //Spoof detection of the name "matomo"
    })();
</script>

On the matomo server I created a script as a proxy (outside the matomo directory):


header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: *");

if (isset($_POST['action'])) {
    $url = base64_decode($_POST['action']);
    $urlParams = [];
    parse_str($url, $urlParams);
    if (!empty($urlParams)) {

        $oCurl = curl_init('https://127.0.0.1/matomo.php');
        curl_setopt($oCurl, CURLOPT_HEADER, TRUE);
        curl_setopt($oCurl, CURLOPT_NOBODY, TRUE);// we don't need body
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($oCurl, CURLOPT_POST, TRUE);
        curl_setopt($oCurl, CURLOPT_FAILONERROR, TRUE);
        curl_setopt($oCurl, CURLOPT_POSTFIELDS, $urlParams);
        curl_setopt($oCurl, CURLOPT_TIMEOUT, 20);
        curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($oCurl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);//Send the user's browser and OS
        curl_exec($oCurl);
        curl_close($oCurl);
        echo "1";
    }
}
@tsteur commented on October 2nd 2019 Member

This was implemented in https://github.com/matomo-org/matomo/pull/14211 but we didn't merge as we don't really want to work around this currently in core. There could be a plugin though maybe providing a solution.

could you maybe comment your thoughts in https://github.com/matomo-org/matomo/issues/7364 or https://github.com/matomo-org/matomo/issues/14207 and I will close this issue as a duplicate?

This Issue was closed on October 2nd 2019
Powered by GitHub Issue Mirror