oe mijn scanner werkt, van bezoek tot bewijsstuk
BeforeYouMick is geen tool die zegt of een site fout zit. Het is een meetketen die vastlegt wat er gebeurde, in drie los van elkaar staande consent-modi, met een hash over elk bewijsstuk zodat een tegenpartij het kan narekenen. Hier staat de hele keten, stap voor stap, inclusief de plekken waar hij liegt als je niet oplet.
Waarom ik hem zelf heb gebouwd¶
Er bestaan scanners die je vertellen of een site "voldoet". Die kon ik niet gebruiken, om twee redenen.
De eerste is dat ze een oordeel geven zonder het bewijs te bewaren. Ik moet aan een organisatie kunnen laten zien wat er gebeurde, niet wat mijn tool ervan vond. Zodra een jurist vraagt "waar blijkt dat uit", is een score van 62 procent waardeloos.
De tweede is dat ze meten als een scanner en niet als een bezoeker. Een kale HTTP-request naar een pagina haalt niet dezelfde trackers op als een echte browser die scrollt, klikt en een video start. Wie zo meet, meet structureel te weinig en concludeert ten onrechte dat het meevalt.
BeforeYouMick is inmiddels versie 4.5 en ruim zevenduizend regels. Hieronder staat wat hij doet, in de volgorde waarin hij het doet.
Stap 1: drie bezoeken, niet een¶
Elke site wordt drie keer bezocht, elk in een vers browserprofiel dat daarna wordt weggegooid:
noop pagina openen, verder niets. Dit is de wettelijke nulmeting.
refuse de weigerknop zoeken, klikken, dan meten.
accept de accepteerknop zoeken, klikken, dan meten.Die drie zijn het hele fundament. De absolute aantallen zeggen weinig. Het verschil tussen de drie is het bewijs, want dat is precies wat de keuze van de bezoeker uitmaakte. Zie Weigeren doet op vier van de vijf sites niets.
De knop zoeken is lastiger dan het klinkt. De scanner herkent eerst het toestemmingsplatform aan de DOM, en gebruikt dan de knopselectors die bij dat platform horen. Lukt dat niet, dan valt hij terug op tekstherkenning, ook binnen iframes, want veel modules draaien in een frame. Vindt hij niets, dan legt hij dat vast als "geen knop gevonden" in plaats van te doen alsof er geweigerd is. Dat onderscheid is belangrijk: een niet gevonden weigerknop is zelf een bevinding.
Stap 2: meten als bezoeker, niet als scanner¶
Binnen elke modus doet de scanner wat een mens ook doet, omdat trackers daarop wachten:
- doorklikken naar maximaal drie interne pagina's;
- scrollen tot onderaan, want veel scripts vuren pas bij scroll;
- klikken op elementen die interactie uitlokken.
Dat is geen cosmetica. In mijn NPI-metingen verschijnt op 23 van de 32 sites een deel van de trackers pas na scroll of interactie, honderden milliseconden na het laden. Wie alleen de eerste seconde meet, mist ze. Zie Niet alles vuurt bij opstart, sommige trackers wachten op jou.
De browser draait met een stealth-laag, zodat de site hem niet direct herkent als automatisering. Dat heeft een prijs die ik hieronder benoem, want die stealth maakt een van de velden onbruikbaar.
Stap 3: alles wat langskomt vastleggen¶
Per modus wordt een volledig HAR-bestand geschreven. Dat is de ruwe opname: elk verzoek, elke header, elke cookie, elke timing. Daarnaast legt de scanner apart vast:
cookies naam, domein, levensduur, secure, sameSite, first of third party
web storage localStorage en sessionStorage, met een oordeel of het tracking is
tracker scripts herkende trackers, met de naam van de leverancier
tracking pixels onzichtbare afbeeldingen van 1x1
response headers CSP, HSTS, X-Frame-Options, Referrer-Policy
consent banner welk platform, of hij zichtbaar was, welke knop is geklikt
privacy links waar de privacy- en cookieverklaring staan
CNAME cloaking via een echte DNS-navraag, niet via de pagina zelfDie laatste is er een die de meeste tools overslaan. Een subdomein van de site zelf kan via een CNAME naar een tracker wijzen. In de browser lijkt dat eigen verkeer, dus first-party bescherming grijpt niet. Alleen een DNS-navraag ontmaskert het. Op 710 van 1.718 overheidssites vond ik dit. Zie CNAME-cloaking zit op vier op de tien overheidssites.
Stap 4: de bestanden zelf lezen¶
Weten dat een script van een tracker geladen wordt is stap een. Weten wat erin staat is stap twee. De scanner downloadt de aangetroffen scripts, met een limiet op grootte, maakt ze leesbaar als ze geminificeerd zijn, en zoekt naar patronen:
- fingerprint-aanroepen, dus code die eigenschappen van je toestel uitleest;
- identificatienummers die letterlijk in de bestandsinhoud staan;
- versluiering, zoals
atobgecombineerd meteval, wat betekent dat de code zichzelf pas bij uitvoering onthult.
Dat laatste vond ik op 25 van de 32 NPI-sites. Versluierde code is niet illegaal, maar het maakt de verwerking oncontroleerbaar voor de partij die er verantwoordelijk voor is, en dat raakt de transparantieplicht.
Stap 5: het bewijs vastspijkeren¶
Dit is het deel waar het instrument van een handig hulpmiddel een bewijsmiddel wordt. Elk artefact, HAR-bestanden, screenshots, gedownloade scripts, wordt in een bewijsmap gezet met een SHA256-hash in een manifest. Dat manifest bevat ook het versienummer van de scanner en het tijdstip.
Waarom dat telt: als ik zes maanden later een organisatie aanspreek en die zegt "dat kan niet, wij hebben dat nooit gehad", dan ligt er een bestand met een hash die aantoont dat het sindsdien niet is aangepast. Zonder die keten is mijn meting een bewering.
Stap 6: van meting naar juridische kwalificatie¶
Pas helemaal aan het eind komt de duiding. Elke bevinding krijgt een ernstniveau en het wetsartikel dat hij raakt. Over de 1.718 gemeten overheidssites leverde dat op:
1.172 KRITIEK
5.177 ERNSTIG
1.964 LET OP
230 CONTROLEERMet als meest voorkomende kwalificaties:
988 AVG art. 28 + Tw 11.7a bekende trackers geladen voor toestemming
846 Tw art. 11.7a trackingcookies gezet, geen banner aangetroffen
724 AVG art. 13 scripts lezen browsereigenschappen uit
710 AVG art. 5(1)(a) + 13 tracking gecamoufleerd achter eigen subdomein
662 AVG art. 32 geen HSTS
608 AVG art. 13 geen privacyverklaring gevonden
604 AVG art. 6 + 28 POST-verzoeken met inhoud naar derden
539 AVG hoofdstuk V ontvangers met servers in een derde landDe labels zijn een hulpmiddel, geen vonnis. Ze wijzen aan welk artikel in beeld komt, zodat een jurist weet waar hij moet kijken. De beoordeling blijft mensenwerk.
Waar de scanner liegt als je niet oplet¶
Elk instrument heeft plekken waar het onbetrouwbaar is. Dit zijn de mijne, en ik noem ze omdat een meetketen zonder bekende zwakke plekken verdacht is.
De referer is onbruikbaar. De stealth-laag past de referer-header aan om detectie te ontlopen. Wie op dat veld attribueert, krijgt valse toewijzingen. Ik gebruik daarom de pageref uit het HAR-bestand om een verzoek aan de juiste pagina te koppelen, nooit de referer.
Diep doorklikken lekt. Als de scanner doorklikt naar een externe pagina, komen die trackers in de meting terecht en lijken ze van de oorspronkelijke site. Navigatie blijft daarom binnen het eigen domein, en verkeer dat na een externe sprong ontstaat wordt apart gehouden.
Een mislukte meting is geen schone site. Als een pagina niet laadt, een botfilter tussenbeide komt of de modus in een time-out loopt, is het resultaat leeg. Leeg betekent niet schoon. Daarom draait er een sanity-controle per modus die vastlegt of de meting compleet is, en alles wat niet compleet is valt buiten de statistiek in plaats van als nul mee te tellen.
Een landlabel is zo oud als de database. De landbepaling per ontvanger komt uit een offline GeoIP-database. Die veroudert. Ik vermeld daarom de datum van de database bij elk dossier, en herbereken oude scans als de database is bijgewerkt.
Een verbinding is geen doorgifte van persoonsgegevens. De scanner ziet dat je toestel een partij benaderde. Wat er in de body zat en wat die partij ermee deed, is een andere vraag met een eigen bewijslast. Zie Een host die je toestel belt is nog geen partij die je data krijgt.
Hoe je dit zelf doet, zonder mijn scanner¶
Je hebt geen zevenduizend regels nodig om de kern te doen. Dit is het minimum dat al bewijskracht heeft:
1. Open een vers browserprofiel, zonder extensies.
2. Ontwikkelaarstools open, netwerktabblad, "preserve log" aan.
3. Laad de pagina en doe niets. Exporteer als HAR. Noem het noop.har.
4. Herhaal met weigeren. refuse.har. En met accepteren. accept.har.
5. Bereken van elk bestand een SHA256-hash en schrijf die op, met datum en tijd.
6. Vergelijk de drie op unieke externe domeinen.
Stap 5 is degene die iedereen overslaat en die het verschil maakt tussen een mening en een dossier. Zie Netwerkverkeer lezen via HAR-files voor het uitlezen zelf.