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

Spoof ad-blocking #14938

Closed
negreanucalin opened this issue Oct 2, 2019 · 2 comments
Closed

Spoof ad-blocking #14938

negreanucalin opened this issue Oct 2, 2019 · 2 comments
Labels
duplicate For issues that already existed in our issue tracker and were reported previously.
Milestone

Comments

@negreanucalin
Copy link

negreanucalin commented Oct 2, 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
Copy link
Member

tsteur commented Oct 2, 2019

This was implemented in #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 #7364 or #14207 and I will close this issue as a duplicate?

@tsteur tsteur closed this as completed Oct 2, 2019
@tsteur tsteur added the duplicate For issues that already existed in our issue tracker and were reported previously. label Oct 2, 2019
@mattab mattab added this to the 3.12.0 milestone Oct 27, 2019
@betavr
Copy link

betavr commented Sep 25, 2020

Here is a server side script for negreanucalin's frontend code that doesn't need curl and leaves ip addresses intact. Put it in a separate file in the webroot next to matomo.php (e.g. mm.php):

<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: *');

$params = array();
parse_str(base64_decode($_POST['action']), $params);
$_REQUEST = $_GET = $params;
$_POST = array();

include "matomo.php";
?>

The url in the ajax call needs to be changed to the url of this file, e.g.

$.ajax({
    type: "POST",
    url: "https://my.matomoinstall.com/mm.php",
    data: {action: btoa(params)}
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate For issues that already existed in our issue tracker and were reported previously.
Projects
None yet
Development

No branches or pull requests

4 participants