3 maart 2020 | 8 minuten leestijd
Lees deel 2 hier!
Sinds 25 mei van vorig jaar is de Algemene Verordening Gegevensbescherming (kortweg AVG) van toepassing. Binnen de AVG wordt een ruime definitie voor het begrip ’persoonsgegevens’ gehanteerd, namelijk “alle informatie over een geïdentificeerde of identificeerbare natuurlijke persoon”. Het gaat hierbij dus om gegevens die direct over een persoon gaan, of gegevens die in combinatie met andere gegevens naar deze persoon te herleiden is.
Persoonsgegevens mogen alleen verwerkt worden voor het doel waarvoor ze verkregen zijn. Dit wordt ‘doelbinding’ genoemd. Om te voorkomen dat organisaties persoonsgegevens verzamelen zonder dit goed te kunnen verantwoorden, moeten zij de uitgangspunten van privacy by design en privacy by default invoeren. Privacy by design houdt in dat een organisatie er al bij het ontwerpen van producten en diensten voor zorgt dat persoonsgegevens goed worden beschermd. Privacy by default houdt in dat een organisatie technische en organisatorische maatregelen moet nemen om ervoor te zorgen dat zij, als standaard, alléén persoonsgegevens verwerkt die noodzakelijk zijn voor het specifieke doel dat zij wil bereiken. Dit betekent bijvoorbeeld dat het niet toegestaan is om meer gegevens te vragen dan nodig is voor het abonneren op een nieuwsbrief.
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 mijn tweedelige blog laat ik je daarom graag zien welke maatregelen je kunt nemen om het onbedoeld verzamelen en verwerken van persoonsgegevens op je website zoveel mogelijk te voorkomen. Daarbij worden persoonsgegevens overschreven, niet verwijderd – mochten er dus onbedoeld bepaalde gegevens verzameld worden, dan kun je deze goed herkennen en de bron ervan opsporen.
In deel 1 introduceer ik de ‘PII-preventiematrix’ en laat ik je zien hoe je met behulp van Google Tag Manager persoonsgegevens kunt blacklisten en whitelisten op een toolonafhankelijke manier – dat wil zeggen: niet voor elk script of elke tool opnieuw, maar slechts één keer voor alle scripts en tools. De uitgewerkte maatregelen zijn bedoeld voor technisch webanalisten, die niet terugdeinzen voor het gebruik van Google Tag Manager en Javascript. Ook maak ik gebruik van reguliere expressie (regex) om patronen te beschrijven.
De maatregelen die je kunt nemen om de verwerking van persoonsgegevens te voorkomen, deel ik in volgens twee classificaties. Samen vormen ze een matrix die ik de PII-preventiematrix noem – hierin verwijst de afkorting PII naar de Engelse term ‘Personal Identifiable Information’ die min of meer gelijk staat aan het begrip ‘persoonsgegevens’. De classificaties zijn:
1) toolonafhankelijk vs. toolafhankelijk.
Bij een toolonafhankelijke oplossing moeten de persoonsgegevens voor elke tool opnieuw vervangen worden. De volgorde waarin verschillende gebeurtenissen plaatsvinden is daarbij als volgt:
Omdat bij de toolafhankelijke oplossing stap III meerdere keren uitgevoerd dient te worden, is dit tamelijk inefficiënt. Daarbij komt dat sommige scripts en/of tools niet eens de mogelijkheid bieden om data zoals URL’s te bewerken alvorens deze door de scripts en/of tools daadwerkelijk te verwerken. De toolonafhankelijke oplossing biedt hiervoor uitkomst. Bij een toolonafhankelijke oplossing is de oplossing tooloverstijgend, en hoeft deze dus slechts een keer toegepast te worden. De volgorde waarin verschillende gebeurtenissen plaatsvinden is daarbij als volgt:
2) blacklisten vs. whitelisten.
Bij blacklisting definieer je een lijst van gegevens die niet verwerkt mogen worden. Staat een bepaald gegeven niet op de blacklist? Dan mag deze verwerkt worden. Whitelisten werkt andersom: hierbij definieer je een lijst van gegevens die wél verwerkt mogen worden. Een bepaald gegeven mag alleen verwerkt worden als deze op de lijst voorkomt. Daarmee is whitelisten dus strenger dan blacklisten.
De classificaties van hierboven resulteren in een kwadrant van 4 oplossingen om de verwerking van persoonsgegevens te voorkomen:
Blacklisten | Whitelisten | |
Toolonafhankelijk | Huidige blog | Huidige blog |
Toolafhankelijk | Deel 2/2 | Deel 2/2 |
In de rest van deze blog zal ik dieper ingaan op het toolonafhankelijk blacklisten en whitelisten van persoonsgegevens met behulp van Google Tag Manager. In de volgende blog zal ik laten zien hoe je blacklisting en whitelisting op Google Analytics kunt toepassen.
Aangezien de meeste scripts op een pagina toegang hebben tot de metadata van een webpagina – denk aan de URL en paginatitel – zijn vooral deze gegevens geschikt om op een toolonafhankelijke manier van persoonsgegeven te ontzien. Dat wil zeggen: voordat de gegevens voor andere scripts beschikbaar is. Het komt regelmatig voor dat deze metadata, bedoeld of onbedoeld, persoonsgegevens bevatten. Denk bijvoorbeeld aan een mailadres dat als queryparameter wordt meegestuurd op de bestemmingspagina van een klantmail. Of een postcode die als queryparameter wordt meegestuurd vanaf een vergelijkingssite.
Met de oplossing van toolonafhankelijk blacklisten specificeer je de reguliere expressies waaraan persoonsgegevens voldoen (de blacklist). Vervolgens check je of deze patronen voorkomen in de gegevens die je wilt verwerken. Als dit het geval is, dan vervang je de substrings die aan deze patronen voldoen. Dit doe je voordat de gegevens door andere scripts verwerkt worden (toolonafhankelijk).
Ter illustratie wil ik je graag laten zien hoe je de URL-parameter “foo” en/of “bar” kunt vervangen door “[REDACTED]” en e-mailadressen door “[REDACTED EMAIL]”. De URL “https://www.domein.nl?foo=waarde&bar=waarde&email=siemon@i-spark.nl&foobar=waarde” wordt dan “https://www.domein.nl?foo=[REDACTED]&bar=[REDACTED]&email=[REDACTED_EMAIL]&foobar=waarde”. Hieronder leg ik stap voor stap uit hoe je dit met behulp van Google Tag Manager kunt realiseren:
1. Definieer je blacklist.
function(){ var piiRegex = [{ name: ‘BLACKLISTED PARAMETER’, regex: /[?&](foo|bar)=([^&$#]+)/gi, replacement: “[REDACTED]”
},{ name: ‘EMAIL’, regex: /(([a-zA-Z0-9_\-\.]+)(@|%40)([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}))/gi, replacement: “[REDACTED_EMAIL]” }];
return piiRegex; } |
2. Creëer een nieuwe functie die persoonsgegevens vervangt.
{{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; } } |
3. Creëer een tag die persoonsgegevens vervangt.
<script>(function(){ var PII = {{PII}};
var URL = {{Page URL}}; var newURL = {{return redactData function}}(URL, PII); if (newURL !== URL) { window.history.replaceState({}, document.title, newURL) }
var title = document.title; var newTitle = {{return redactData function}}(title, PII); if (newTitle !== title) { document.title = newTitle; }
window.dataLayer = window.dataLayer || []; window.dataLayer.push({ “event”: “piiRedacted”, “Page URL”: newURL });
})(); </script> |
4. Creëer een trigger op basis van het “piiRedacted” event.
Maak een nieuwe trigger aan van het type ‘Aangepaste Gebeurtenis’ op basis van het “piiRedacted” event. Dit event geeft het moment aan dat alle handelingen in de Custom HTML tag van hierboven uitgevoerd zijn – op dit moment zijn de URL en titel van de webpagina dus ontzien van persoonsgegevens.
5. Vervang de bestaande ‘All Pages’ trigger door de nieuwe “piiRedacted” trigger
Om ervoor te zorgen dat tags van andere scripts pas geladen worden nadat de URL en paginatitel van persoonsgegevens zijn ontzien, moet de ‘All Pages’ trigger op bestaande tags vervangen worden door de nieuwe trigger op basis van het “piiRedacted” event.
Met de oplossing van toolonafhankelijk whitelisten definieer je de gegevens die geen persoonsgegevens zijn (de whitelist). Vervolgens buig je deze om tot blacklist-patronen, omdat je juist de waarden wilt vervangen die niet in de whitelist voorkomen. Een voorbeeld zal dit duidelijk te maken.
Ter illustratie wil ik de waarde van alle URL-parameters vervangen door “[REDACTED]”, behalve die van de parameters “foo” en “bar” – dit is mijn whitelist. Concreet betekent dit dat de URL “https://www.domein.nl?foo=waarde&bar=waarde&email=siemon@i-spark.nl&foobar=waarde” vervangen wordt door “https://www.domein.nl?foo=waarde&bar=waarde&email=[REDACTED]&foobar=[REDACTED]”. Hieronder leg ik stap voor stap uit hoe je dit met behulp van Google Tag Manager kunt realiseren:
1. Definieer je blacklist
function(){ var piiRegex = [{ name: ‘NON-WHITELISTED PARAMETER’, regex: /([?&](?!((foo|bar)=))[^=]+=)([^&$#])+/gi, replacement: “$1[REDACTED]”
}]
return piiRegex; } |
De reguliere expressie is nu ingewikkelder door het gebruik van een negative lookahead. Voor de liefhebber leg ik de reguliere expressie met de negative lookahead graag stukje voor stukje uit:
Eerste capturing group: match een “?” of “&” die niet gevolgd wordt door “foo=” of “bar=”
Match een ‘?’ of ‘&’.
Negative lookahead: match het voorgaande alleen als dit niet gevolgd wordt
door de reguliere expressie.
De string “foo” of “bar” gevolgd door “=”.
“foo|bar” is je whitelist!
Match elk karakter behalve “=” minimaal 1 keer tot “=”
Tweede capturing group: match elk karakter behalve “&”, “$” (einde van de string) of “#” minimaal 1 keer
Het gebruik van bovenstaande reguliere expressie betekent dat de URL “https://www.domein.nl?foo=waarde&bar=waarde&email=siemon@i-spark.nl&foobar=waarde” 2 matches geeft, namelijk “&email=siemon@i-spark.nl” en “&foobar=waarde”. Er komen immers 2 parameters voor die niet voldoen aan de whitelist binnen de negative lookahead, en dat zijn “email” en “foobar”. Ik wil alleen de parameterwaarde vervangen door “[REDACTED]” en daarom moet de 1e capturing group van elke match – “&foo=” en “&bar=” – behouden blijven. Dit doe ik door de volledige regex matches te vervangen door “$1[REDACTED]”.
De stappen b t/m e blijven voor het toolonafhankelijk whitelisten gelijk als hierboven beschreven voor het toolonafhankelijk blacklisten.
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!
Siemon