apier versus code: de verklaring en de uitvoering
Deze notitie bundelt een aantal losse bevindingen die bij elkaar horen. Papier versus code: de verklaring en de uitvoering.
Wat op papier staat en wat de code doet¶
Privacy wordt in Nederland vooral op papier behandeld. Er is beleid, er zijn privacyverklaringen, er zijn juridische stukken en soms een DPIA. Dat papier beschrijft wat een organisatie zegt te doen met de gegevens van haar bezoekers. De werkelijkheid ligt ergens anders. Die ligt in de code, in wat een site of app op het moment van gebruik daadwerkelijk uitvoert. Daar kijkt bijna niemand.
Het papier en de code zijn twee losse dingen. Het papier is de belofte. De code is de uitvoering. Ze kunnen ver uiteenlopen zonder dat iemand het merkt, want ze worden door verschillende mensen gemaakt en door verschillende mensen gelezen. De jurist stelt de verklaring op. De ontwikkelaar schrijft de code en plakt er een tagmanager bij. De bestuurder ondertekent het beleid. Wie de drie naast elkaar legt en controleert of ze hetzelfde zeggen, is zeldzaam. Die kloof tussen de mensen aan de knoppen en de mensen met de pen is een terugkerend patroon, zie De bouwers en de beslissers weten vaak niet van elkaar.
Ik ga ervan uit dat de meeste organisaties het niet expres verkeerd doen. Het papier klopt in hun hoofd. Ze hebben een cookiebanner geplaatst, een verwerkersovereenkomst getekend en een DPIA in een la liggen. Wat de pagina live over de lijn stuurt naar tientallen andere partijen, heeft niemand nagemeten. De belofte en de uitvoering leven in aparte werelden, en zolang niemand ze samenbrengt, blijft het verschil onzichtbaar.
Alleen de uitvoering is te meten¶
Een privacyverklaring kan het ene beloven terwijl de code het andere doet. Beide zijn op datzelfde moment waar. De verklaring staat er echt, en de code draait echt. Ze spreken elkaar tegen, en toch bestaan ze naast elkaar. Van die twee is er precies één die je kunt meten. De verklaring is een tekst over intenties. De code is een gebeurtenis die je kunt vastleggen.
Hier zit ook de juridische kant. Artikel 5 lid 2 van de AVG legt de verwerkingsverantwoordelijke een verantwoordingsplicht op. Die moet kunnen aantonen dat de verwerking aan de beginselen voldoet. Het papier is precies dat aantonen: de verklaring, het register, de DPIA. De meting toetst of het aantonen klopt. Zolang niemand meet, is de verantwoordingsplicht een stapel documenten die zichzelf goedkeurt.
Meten doe ik door het echte verkeer van een pagina vast te leggen. Een browser die de site bezoekt schrijft elke aanvraag weg in een HAR-bestand, een JSON-log van alles wat er over de verbinding ging. Daarin staat welke hosts zijn aangeroepen, welke cookies meegingen en welke gegevens zijn verstuurd, zie Netwerkverkeer lezen via HAR-files. Dat log is de uitvoering, zwart op wit.
import json
from urllib.parse import urlparse
with open("bezoek.har", encoding="utf-8") as f:
har = json.load(f)
eigen = "voorbeeld.nl"
derden = {}
for entry in har["log"]["entries"]:
host = urlparse(entry["request"]["url"]).hostname or ""
if host and not host.endswith(eigen):
derden[host] = derden.get(host, 0) + 1
for host, n in sorted(derden.items(), key=lambda x: -x[1]):
print(f"{n:4d} {host}")Dit telt de aanvragen naar hosts die niet bij het eigen domein horen. Als de verklaring zegt dat er geen gegevens naar derden gaan en deze lijst staat vol met advertentie- en analyse-domeinen, dan is de tegenspraak gemeten. De verklaring blijft staan, en de lijst blijft staan. De lijst wint, want die is controleerbaar.
Bij het meten geldt één harde eis. Meet zoals een echte bezoeker, met een echte browser die de pagina rendert en de scripts uitvoert, zie Meet zoals een bezoeker, niet zoals een scanner. Een kale scanner die alleen de HTML ophaalt, ziet de helft niet, want veel tracking laadt pas na uitvoering van JavaScript of pas na een klik op de banner. En let op de andere kant: een lege lijst kan ook betekenen dat de meting niet goed liep. Een mislukte meting bewijst geen schone app, zie Een mislukte meting is geen schone app.
Soms staat de schending letterlijk in de code¶
Meestal is de tegenspraak subtiel. Je moet het verkeer lezen en de partijen thuisbrengen om te zien wat er misgaat. Soms is het grover. Bij de Kiesraad stond in de configuratie de instelling respectVisitorsPrivacy op false. Met zoveel woorden, in de code, voor iedereen die keek. De privacy van de bezoeker werd niet gerespecteerd, en dat stond er letterlijk als zodanig ingesteld.
Het bijzondere is niet dat het verborgen was. Het was er niet in verstopt. Het stond er, leesbaar, met een naam die precies zegt wat de schakelaar doet. Het bijzondere is dat niemand het had gelezen. De blindheid is hetzelfde of de schending nou luid of stil in de code staat. Zolang niemand de code naast de belofte legt, maakt het niet uit hoe openlijk het erin staat. Het gaat over meer dan de Kiesraad; dit patroon zag ik breder op overheidssites, zie Wat de meting op overheidssites liet zien.
Twee bewijsniveaus, en het verschil hoort in het rapport¶
Er zijn twee manieren om zo'n bevinding hard te maken, en ze zijn niet gelijk. De eerste vind je in de code zelf. Een instelling op false, een tracker-SDK in een gedecompileerde app, een endpoint in de broncode. Dat staat vast in die code. De tweede zie je live gebeuren, op de verbinding, in de HAR: het toestel roept die server echt aan en stuurt die gegevens echt mee.
Beide zijn bewijs. Ze zitten op een verschillend niveau. Een SDK in de code toont dat de mogelijkheid is ingebouwd. Het live verkeer toont dat de mogelijkheid ook wordt gebruikt tijdens een gewoon bezoek. Een app kan een tracker-bibliotheek meedragen die onder de geteste omstandigheden nooit afvuurt. Dan is de code-bevinding waar en is de live-bevinding afwezig, en dat verschil is belangrijk genoeg om op te schrijven.
Daarom label ik elke bevinding op zijn niveau: gemeten, afgeleid of vermoed, zie Label elke bevinding op bewijsniveau. Een naam die in de code opduikt, is een aanwijzing en nog geen sluitend bewijs dat de gegevens ook echt bij die partij aankomen, zie Een naam in de code is nog geen tracker en Een aanwijzing is nog geen bewijs. Wie de twee niveaus door elkaar haalt, maakt een rapport dat op de eerste tegenwerping omvalt. Wie ze scheidt, houdt een rapport over dat elke controle doorstaat.
Code toont het gedrag, het waarom blijft buiten de meting¶
Er is een grens aan wat de code je vertelt. Je leest eruit af wat een app doet. Je leest er niet uit af met welke bedoeling. Het verkeer laat zien dat er een identifier naar een advertentieveiling gaat. Het zegt niets over of dat opzet was, slordigheid, een meegeleverde SDK die iemand vergat uit te zetten, of een bewust verdienmodel.
Een uitspraak over motief is een aanname. Kwade wil, hebzucht, een plan om mensen te verhandelen: dat zijn interpretaties die je op de meting plakt, geen deel van de meting. Ik houd die twee strikt uit elkaar. Ik schrijf op wat er gebeurt en op welk niveau ik het zag. Het waarom laat ik aan wie erover gaat, aan de toezichthouder, aan de organisatie zelf, aan de rechter.
Dat is geen terughoudendheid uit beleefdheid. Het is dezelfde discipline als bij de bewijsniveaus. Zodra ik een motief toeschrijf, verlaat ik het meetbare en ga ik gissen. Dan wordt mijn rapport aanvechtbaar op een punt dat ik nooit heb gemeten. Een gedraging die technisch klopt en toch een verkeerde indruk wekt, is trouwens een eigen categorie die ik apart benoem, zie Technisch juiste uitspraken kunnen een verkeerde indruk wekken. En mijn eigen overtuiging telt niet als meting; een stellige getuige is nog geen betrouwbare bron, zie Een overtuigde getuige is geen betrouwbare meting.
Zelfs de keurmeesters zakken voor hun eigen toets¶
Het venijn zit in de partijen die anderen op privacy aanspreken. Toezichthouders, privacy-organisaties, adviesbureaus die keurmerken uitdelen. Je zou verwachten dat hun eigen code de belofte waarmaakt die zij van anderen eisen. In de meting valt dat tegen. Ook op hun sites laadt de code dingen die ze bij een ander zouden afkeuren, zie De partijen die privacy keuren, zakken zelf voor de toets.
Dat maakt het punt scherper. Het gaat niet om onwil van een enkele achterblijver. De kloof tussen papier en code loopt dwars door de partijen heen die het papier het beste kennen. Zij hebben de verklaringen, zij kennen de wet, en toch draait er in hun eigen uitvoering iets anders dan ze opschrijven. Dat is precies waarom de code de eerlijke bron is. Die trekt zich niets aan van wie je bent of wat je beweert.
De DPIA hoort hier ook thuis. Een DPIA die niemand kan inzien, beschermt niemand. Het document bestaat, het vinkje is gezet, en de inhoud blijft binnen, zie Een DPIA die niemand kan inzien, is geruststelling, geen afweging. Op papier is er verantwoording afgelegd. In de praktijk kan niemand die verantwoording toetsen. Weer die verantwoordingsplicht uit artikel 5 lid 2, die op papier wordt afgevinkt en in de uitvoering nooit wordt nagemeten.
Wat dit voor mijn werk betekent¶
Voor mij volgt hier een vaste werkwijze uit. Ik begin bij een vermoeden en werk toe naar een bevinding die op de meting rust, zie Mijn werkwijze: van vermoeden naar bevinding. Het vermoeden komt vaak van het papier: een verklaring die te mooi klinkt, een banner die te makkelijk sluit. De bevinding komt altijd van de code, uit de HAR, uit het echte verkeer. Wat ik publiceer, is het deel dat ik heb gezien.
Ik leg dezelfde meetlat langs de overheid en langs een willekeurige app, zie Dezelfde meetlat voor de overheid en de app in je broekzak. Een overheidssite die zegt de bezoeker te beschermen, krijgt dezelfde HAR-analyse als een gratis spelletjes-app. Het papier verschilt, de toon verschilt, de wettelijke plicht verschilt. De meting is gelijk. Dat is de enige manier om eerlijk te blijven, want de code kent geen aanzien des persoons.
De kern is simpel. Privacy wordt behandeld als een papieren kwestie, en de echte inhoud zit in code die vrijwel niemand bekijkt. Zolang dat zo blijft, kun je een organisatie die het goed opschrijft niet onderscheiden van een die het goed doet. Ik probeer dat gat te dichten door te meten, één bezoek per keer, en op te schrijven wat er echt over de lijn ging.
Zie ook Netwerkverkeer lezen via HAR-files, Label elke bevinding op bewijsniveau en De partijen die privacy keuren, zakken zelf voor de toets.