The DoNotTrack feature is not working properly for cached pages.

The implementation of DoNotTrack feature does this (according to code in googleanalytics.module):

"Disable tracking if caching is disabled or a visitors is logged in and have opted out from tracking via DNT (Do-Not-Track) header."

This means that if:
- a site has caching enabled and the user is anonymous
- the GA Universal web tracking opt-out is set to "On"
- the user sends the HTTP_DNT header

Things will not work properly when Drupal is caching the page.

If a user requests the page and do not have the HTTP_DNT header set, a GA code will be put into the page (correct). But if the next user requests the same page (this has been cached) the GA code will still excist regardless if the HTTP_DNT header is sendt or not.

It seems that checking if the user is logged in or not should be handled by other parts of the code (and i think it is). And that checking the HTTP_DNT header should be handled clientside (not serverside by the GA drupal module).

So the problem here is that the HTTP_DNT check will not work properly with cached pages, due to the fact that the check is done serverside.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

candalt created an issue. See original summary.

hass’s picture

If a user requests the page and do not have the HTTP_DNT header set, a GA code will be put into the page (correct). But if the next user requests the same page (this has been cached) the GA code will still excist regardless if the HTTP_DNT header is sendt or not.

Please prove with a test. The current test do not show this issue.

hass’s picture

Status: Active » Postponed (maintainer needs more info)
candalt’s picture

After digging a bit more, i found this related issue https://www.drupal.org/node/2173433.

It seems that the check for DNT header is designed to work this way?

But this, i think, is not a very good thing. This means on Drupal sites with anonymous users and cache enabled when the user visits and sends the DNT header. The GA module will not respect the DNT header.

I guess just about all drupal sites out there have cache enabled and anonymous users.

In my humble opinion it would be better to let the GA module handle this clientside, not serverside like today. I guess all major browsers today support the "doNotTrack" feature in javascript, and the support gets better all the time.

The tracking script could then be embedded on the site all the time, but a clientside check would be made to see if the browser has the "doNotTrack" set to "true". If so...then send the pageview hit to Google.

osopolar’s picture

Status: Postponed (maintainer needs more info) » Needs work

I didn't create a test to prove #1: "The DoNotTrack feature is not working properly for cached pages", as requested in #2. Anyway it seems that for multiple reasons DoNotTrack (DNT) is not respected for cached pages.

1. It's already said in the settings form: "Universal web tracking opt-out ... This feature is currently limited to logged in users and disabled page caching". This is because Tracking is always enabled for anonymous visitors visiting cached pages, if it is allowed for anonymous visitors:

See _googleanalytics_visibility_header():

  if (($account->uid || variable_get('cache', 0) == 0) && variable_get('googleanalytics_privacy_donottrack', 1) && !empty($_SERVER['HTTP_DNT'])) {
    // Disable tracking if caching is disabled or a visitors is logged in and
    // have opted out from tracking via DNT (Do-Not-Track) header.
    return FALSE;
  }

For anonymous user uid is 0 (= FALSE in above condition), the cache variable is 1 for enabled page-cache, so 1 == 0 is FALSE to, which means the code in the if statement won't get executed, therefore the function seems to always return TRUE for anonymous users when caching is enabled.

2. AFAIK hook_page_alter() is not called for cached pages, for caches like varnish and boost that is sure, as drupal won't get involved for that kind of page delivery, see also #2205193: Google Analytics works only after clearing cache and #2173433: No GA code with alternative page caching engines and DNT header. hook_page_alter() is also not called if pages are served from drupal cache, see https://api.drupal.org/api/drupal/modules%21system%21system.api.php/func....

It seems to be better to not do the DNT check on server side at all, but in JavaScript with Navigator.doNotTrack, but that is experimental technology (Working Draft).

Any interests to change the implementation of DNT to JavaScript which should also work with cached pages?

artfulrobot’s picture

Yes, it should be client side.

The current implementation made me laugh and cry. People who have DNT set do so because they don't want to be tracked. If they need to log in and set an option and even then only visit uncached pages for their wishes to be recognised, that's a very small subset of honoured DNT pages.

Could we simply wrap the code snippet like

if (! ((window.navigator && (window.navigator.doNotTrack || window.navigator.msDoNotTrack)) || window.doNotTrack)) {
...rest of code...
}

https://developer.mozilla.org/en-US/docs/Web/API/navigator/doNotTrack

hass’s picture

Can you write a plugin like http://www.outfox.com/do-not-track-for-google-analytics/ for the module? That would solve a lot of our troubles and is clean to integrate without changing the tracking code.

abrlam’s picture

Attached is the patch based on @artfulrobot approach.

abrlam’s picture

Use this patch instead as it does DNT check on Analytics and AdSense.

hass’s picture

See #7

phjou’s picture

I agree with @abrlam that the DNT check should be done using JS.

abrlam’s picture

Status: Needs work » Needs review

@hass, I'm not sure if #7 is GDPR compliant. My interpretation of GDPR is that if users have DNT enabled on their browser, nothing should be sent to the Google Analytics. Correct me if I'm not on the right track.

@phjou, you can credit @osopolar and @artfulrobot for it. Their comments led to this patch (#9).

abrlam’s picture

abrlam’s picture

hass’s picture

Version: 7.x-2.x-dev » 8.x-3.x-dev
Status: Needs review » Needs work

See #7

Anybody’s picture

#14 works as JS based solution and is much better than the current solution in PHP. This feature is also contained in #3060312: Better GDPR compliance: Fix Do not track & EU Cookie Privacy integration and it would be great to have your help there to have a working 8.x-3.x GDPR patch. Thank you!

I'd suggest to close this as duplicate in favor of #3060312: Better GDPR compliance: Fix Do not track & EU Cookie Privacy integration?

Anas_maw’s picture