Zo voorkom je privacygevoelige dataverzameling – deel 2/2: Blacklisten en whitelisten in Google Analytics

3 maart 2020 | 6 minuten leestijd

Gepubliceerd door Marketingfacts 

Heb je deel 1 gemist? Lees hem hier!

Om persoonsgegevens te mogen verzamelen, moeten ze aan een of meer van de beginselen van verwerking voldoen, zoals rechtmatigheid, transparantie, doelbinding en juistheid. Voldoet een persoonsgegeven hier niet aan, dan is het verzamelen ervan niet toegestaan. De kans bestaat echter dat je onrechtmatig persoonsgegevens verwerkt, zonder dat je je hier bewust van bent. Bijvoorbeeld doordat je tools of scripts op je website gebruikt die meten op welke URL een bezoeker zich bevindt. Deze URL kan bijvoorbeeld een e-mailadres bevatten als de klant via een klantmail je website bezoekt. 

In deel 1 van deze blog deelde ik de zogenaamde ‘PII-preventiematrix’ en heb ik laten zien hoe je blacklisting en whitelisting van persoonsgegevens toolonafhankelijk kan toepassen. Daarbij werd ook duidelijk dat, met de toolonafhankelijke oplossing, de onbedoelde verzameling van persoonsgegevens beperkt bleef tot de persoonsgegevens in de metadata van een pagina. Daarom ga ik in dit tweede deel van de blog in op blacklisting en whitelisting middels een toolafhankelijke oplossing. Hierin laat ik zien hoe je PII kan blacklisten en whitelisten in Google Analytics. Ik sluit af met een aanbeveling over de meest geschikte oplossing en leg stap voor stap de implementatie hiervan uit.


Blacklisting in Google Analytics

In zijn blog laat Simo Ahava zien hoe het customTask veld gebruikt kan worden om de hit die naar de Google servers verstuurd wordt te checken op reguliere expressies van persoonsgegevens. Persoonsgegevens die in de hit voorkomen, worden vervolgens vervangen door bijvoorbeeld de tekst “[REDACTED_EMAIL]”.

Het nette van de manier die Simo beschrijft, is dat de hele hit gecheckt wordt op de aanwezigheid van bepaalde reguliere expressies. Dus bijvoorbeeld niet alleen de URL of paginatitel, maar alle hit parameters die naar de Google servers verstuurd worden. Daarbij is de lijst van reguliere expressies die binnen de customTask gebruikt wordt flexibel, in de zin dat de lijst met reguliere expressies gemakkelijk aangepast en uitgebreid kan worden naar de wensen van jouw organisatie. 


Whitelisting in Google Analytics

Het nadeel van blacklisting is dat je van tevoren moet weten aan welk patronen de verschillende types persoonsgegevens voldoen. En vaak weet je dat niet. Denk bijvoorbeeld aan een zoekterm die op je website ingevoerd wordt: hoe onderscheid je bijvoorbeeld een zoekterm naar een product van een zoekterm die een persoonsgegeven bevat? De veilige optie is dan om het zoekveld helemaal niet te meten. 

Soms kun je echter gebruik maken van whitelisting – alleen de waarden die voldoen aan door jou gespecificeerde patronen worden verzameld. Patronen die er niet aan voldoen, dienen vervangen worden. Hiervoor moet de whitelist eerst omgebogen tot een blacklist – dit kwam in deel 1 van deze blog aan bod. 

Het gebruik van whitelisting verlaagt het risico om onbedoeld persoonsgegevens te verzamelen. Daar staat tegenover dat je het risico loopt om gegevens mis te lopen die geen persoonsgegevens bevatten als je whitelist niet volledig is. En die kans is groot. Hoe kun je immers alle teksten die je wilt whitelisten specificeren? 


Welke oplossing om de onbedoelde verzameling van persoonsgegevens te voorkomen is dan de beste?

Het doel van deze en vorige blog was om jou te laten zien dat er verschillende benaderingen zijn om de verzameling van persoonsgegevens te voorkomen en om jou hierin enkele handreikingen te bieden. Maar welke van de beschreven oplossingen uit deel 1 en 2 van deze blog is dan de beste? Disclaimer: het doorvoeren van de beschreven oplossingen is geenszins volledig om aan de privacywetgeving te voldoen. 

Mijn persoonlijke voorkeur gaat altijd uit naar whitelisting waar mogelijk. Hiermee loop je immers het laagste risico om onbedoeld persoonsgegevens te verzamelen. We hebben gezien dat URL-parameters hier bij uitstek geschikt voor zijn. Echter, in theorie is het mogelijk dat er zelfs in de waarde van een gewhiteliste parameter, bijvoorbeeld een campagne tracking parameter, persoonsgegevens staan. Ook kun je niet alle data die toegestaan is om te verzamelen, vangen in whitelists. Vanwege deze redenen ontkom je er niet aan om ook blacklists te hanteren. Waar mogelijk is een combinatie van whitelisting en blacklisting daarom aan te raden. 

Gebruik je alleen Google Analytics op je site en ben je op korte termijn niet van plan andere scripts te gebruiken? Dan volstaat het om te kiezen voor de Google-Analyticsspecifieke oplossing om de verzameling van persoonsgegevens te voorkomen (nogmaals, credits hiervoor gaan naar Simo Ahava). De toolonafhankelijke oplossing waarbij persoonsgegevens in de URL en titel van de webpagina worden vervangen heeft in dit geval geen meerwaarde. Immers, bij de Google-Analyticsspecifieke oplossing wordt de volledige payload gecheckt op PII-patronen en deze payload is inclusief de pagina-URL en paginatitel. Wel is het aan te raden om een whitelist te herschrijven als blacklist en deze binnen de customTask op te nemen.

Gebruik je ook andere scripts dan alleen die van Google Analytics? Dan is het aan te raden om toolonafhankelijk een combinatie van blacklisting en whitelisting te gebruiken om de verzameling van persoonsgegevens in de URL en titel van een webpagina te voorkomen. Daarnaast kun je binnen Google Analytics de verzameling van persoonsgegevens voorkomen door het customTask veld te gebruiken. Ook hiervoor is het aan te raden een combinatie van blacklisting en whitelisting te gebruiken. De combinatie van toolonafhankelijke en toolafhankelijke black- en whitelisting wordt in het volgende hoofdstuk beschreven.

Het gebruik van een combinatie van toolonafhankelijke en toolafhankelijke blacklisting en whitelisting – de implementatie

Het is belangrijk om je Google Tag Manager overzichtelijk te houden. Hiermee bespaar je uiteindelijk tijd en voorkom je fouten. Voor de implementatie van toolafhankelijke en toolonafhankelijke black- en whitelisting betekent dit 2 dingen: 

1) Definieer 1 keer een blacklist, inclusief de omgebogen whitelist

2) Definieer 1 keer een functie om de blacklist-patronen in de gegevens te vervangen.

Roep vervolgens deze variabelen aan vanuit zowel de toolonafhankelijke als toolafhankelijke oplossing om persoonsgegevens te verzamelen.

a    Definieer je blacklist

  •       Maak een nieuwe variabele aan van het type ‘Aangepaste JavaScript-macro’ en noem deze “PII”. Zie het voorbeeld hieronder.
  •       Definieer binnen de nieuwe variabele een array met daarin voor elk type gegeven waarvan je de verzameling wilt voorkomen een object. In ons voorbeeld gaat het om twee typen gegevens, namelijk niet-gewhiteliste parameters en e-mailadressen.
  •       Geef de objecten die je voor elke type gegeven gedefinieerd hebt 3 keys: ’name’, ‘regex’ en ‘replacement’. Geef voor de name key een string op waarmee je beschrijft om welk type gegeven het gaat. Dit is vooral voor jezelf handig. Geef voor de regex key de reguliere expressie op waaraan het type gegeven voldoet. Geef voor de replacement key de string op waarmee het patroon vervangen moet worden.
  •       Return de gedefinieerde array. 

Doordat de reguliere expressies in een aparte variabele staan, kunnen deze zowel gebruikt worden om de metadata van een pagina op de gespecificeerde patronen te checken (toolonafhankelijk) als ook binnen de customTask in Google Analytics (toolafhankelijk). Dit betekent dat je een aanpassing in je blacklist op slechts 1 plaats hoeft door te voeren.

 

function(){  var piiRegex = [{       name: ‘NON-WHITELISTED PARAMETER’,       regex: /([?&](?!((foo|bar)=))[^=]+=)([^&$#])+/gi,

       replacement: “$1[REDACTED]”

  },{

       name: ‘EMAIL’,

       regex: /(([a-zA-Z0-9_\-\.]+)(@|%40)([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}))/gi,

       replacement: “[REDACTED_EMAIL]”

  }];

 

  return piiRegex;

}

  b.   Creëer een nieuwe functie die persoonsgegevens vervangt

  •       Maak een nieuwe variabele aan van het type ‘Aangepaste JavaScript-macro’ en noem deze “return redactData function”. Gebruik hierbinnen de onderstaande Javascript.
  •       De variabele returnt een functie met 2 parameters: de 1e parameter is een gegevensstring, de 2e parameter is de eerder gedefinieerde blacklist die we “PII” hebben genoemd. Voor elk van de gedefinieerde gegevens in de blacklist checkt de functie of de reguliere expressie voorkomt in de gegevensstring, totdat er een match is. Op dat moment wordt de gegevensstring vervangen door de bijbehorende waarde van de replacement key. Het resultaat is dat de functie een gegevensstring teruggeeft waarbij de gegevens die in onze gedefinieerd blacklist “PII” staan, vervangen zijn.

Ook hiervoor geldt: door de functie in een aparte variabele te plaatsen kun je deze altijd aanroepen vanuit iedere tag of Javascript-variabele binnen Google Tag Manager. En dus ook vanuit zowel de toolonafhankelijke als de toolafhankelijke oplossing om persoonsgegeven te vervangen. Daarvoor geef je de gegevensstring en de gedefinieerde blacklist “PII” als argumenten mee. Dat ziet er dan als volgt uit: {{return redactData function}}(gegevensstring, {{PII}})

function(){  return function(data, PII){    for (var i = 0; i < PII.length; i++){   data = data.replace(PII[i].regex, PII[i].replacement);

};

return data;

  }

}

 Met het creëren van de blacklist (stap a) en de functie om geblackliste patronen in gegevens te vervangen (stap b) staat de basis voor onze implementatie klaar. Wat ons rest, is om zowel de toolonafhankelijke als ook de toolafhankelijke oplossing gebruik te laten maken van deze variabelen. Voor de toolonafhankelijke oplossing verwijs is ik je hiervoor naar de stappen c t/m e van het vorige deel van deze blog. Voor de Google Analytics-specifieke oplossing dient het customTask veld als volgt aangepast te worden, zodat bovenstaande variabelen aangeroepen worden:  

function() {  return function(model) {var piiRegex = {{PII}};var globalSendTaskName = ‘_’ + model.get(’trackingId’) + ‘_sendHitTask’;

// Fetch reference to the original sendHitTask

var originalSendTask = window[globalSendTaskName] = window[globalSendTaskName] || model.get(‘sendHitTask’);

 

var i,j, hitPayload, parts, val;

// Overwrite sendHitTask with PII purger

model.set(‘sendHitTask’, function(sendModel) {

   hitPayload = sendModel.get(‘hitPayload’).split(‘&’);

   for (i = 0; i < hitPayload.length; i++) {

     parts = hitPayload[i].split(‘=’);

     // Double-decode, to account for web server encode + analytics.js encode

     try {

       val = decodeURIComponent(decodeURIComponent(parts[1]));

     } catch(e) {

       val = decodeURIComponent(parts[1]);

        }

    

        piiRegex.forEach(function(pii){

       val = {{return redactData function}}(val, piiRegex);

     });

  

     parts[1] = encodeURIComponent(val);

     hitPayload[i] = parts.join(‘=’);

   }

      sendModel.set(‘hitPayload’, hitPayload.join(‘&’), true);

   originalSendTask(sendModel);

});

  };

}

 Met deze implementatie heb je alle vier de oplossingen uit de PII-matrix toegepast. De volgende stap is om met behulp van Google Analytics te monitoren hoe vaak en op welke plaatsen het vervangen van gegevens nodig is gebleken, te herkennen aan de tekst “REDACTED”. Gebruik dit als input om het gebruik van deze gegevens in URL’s volledig te voorkomen. Succes!

Wil je graag hulp met het doorvoeren van de bovengenoemde oplossingen? Of wil je weten welke oplossing het beste past bij jouw website? Neem vrijblijvend contact met ons op!

neem contact op

Siemon