Ook een schone app kan in de databrokerlijst staan
Een lichte, nette app met nauwelijks advertenties beschermt je niet automatisch. Een partner in de keten is genoeg om je gegevens bij een databroker te laten belanden. Weinig trackingverkeer en toch in de lijst staan zijn twee losse vragen.
Twee vragen die los van elkaar staan¶
Er zijn twee vragen die vrijwel iedereen als één vraag behandelt.
De eerste is: hoeveel volgverkeer maakt deze app? Dat meet je aan het netwerk. Je legt een sessie vast, telt de verzoeken en kijkt waar ze heen gaan.
De tweede is: staat deze app in een handelslijst van een databroker? Dat meet je niet aan het netwerk van die app. Dat lees je in de lijst zelf, of in de SDK's die de app meedraagt.
Deze notitie bestaat omdat het antwoord op de eerste vraag het antwoord op de tweede niet voorspelt. Een ov-app met ongeveer één procent advertentieverkeer stond toch in een gelekte databrokerlijst (grondveld bij deze notitie in genereer_sporen.py). Eén procent. Een app die je in elke ranglijst van dataslurpers onderaan zou plaatsen, en die tegelijk in de handel zat.
Vergelijk dat met de app uit dezelfde reeks waarin 87 procent van de netwerkverzoeken en 54 procent van de bytes naar de advertentieketen ging (grondveld bij het-meeste-verkeer-van-je-app-gaat-niet-naar-de-app). Twee uitersten van dezelfde meetlat, en allebei in de lijst. Zie Het meeste verkeer van je app gaat niet naar de app.
Hoe een lichte app in een lijst belandt¶
De route loopt via de bouwsteen, niet via het verkeer dat je ziet.
Een ontwikkelaar wil een functie snel werkend hebben. Een kaartje, een advertentiebalk, een analysepakket, een crashmelder. Hij plakt een kant-en-klaar stuk code in zijn app, een SDK. Die SDK levert de functie, en stuurt in ruil de positie van het toestel door naar de partij die de SDK maakte. De positie van het toestel is de betaling (de-locatiedatahandel-heeft-vaste-spelers in mick_bodies.py). Zie De locatiedatahandel draait op een handvol vaste spelers.
Voor de broker is dit een efficiënt model. Hij hoeft zelf geen populaire app te bouwen en geen gebruikers te werven. Hij levert een handige component aan honderden ontwikkelaars, en elk van die apps wordt een aanvoerkanaal.
Daar zit de reden waarom lichtheid niet beschermt. Eén SDK is genoeg. Die ene SDK hoeft nauwelijks verkeer te maken, want een locatie is een handvol bytes en hij hoeft maar af en toe te vertrekken. Op je verkeersteller valt dat weg in de ruis. In de lijst van de broker staat je toestel er wel.
De namen zijn bovendien beperkt in aantal. Ik legde een index van honderden apps naast de bekende broker-SDK-lijsten, en dezelfde spelers keerden steeds terug: X-Mode, dat nu Outlogic heet en van de Amerikaanse FTC een verbod kreeg, Gravy en Venntel, die locatiedata leverden aan Amerikaanse overheden, plus OneAudience, Sense360, SignalFrame, Fysical, Placed en Predicio (nieuwe_entries.py, grondveld bij de-locatiedatahandel-heeft-vaste-spelers).
De tweede route: de veiling erachter¶
Er is nog een manier waarop een nette app in de handel belandt, en die loopt via de markt waarop hij is aangesloten.
Een app kiest een verkoopplatform. Via dat platform komt hij automatisch in contact met het hele veld aan bieders dat daarop is aangesloten. De app kiest die bieders niet één voor één. In een echte bid-respons uit één app zaten zeven biedende partijen, en zes daarvan staan ook in de partnerlijst van een totaal andere app (onverwante-apps-delen-dezelfde-veiling in mick_bodies.py). Zie Onverwante apps sturen je profiel dezelfde veiling in.
Het biedverzoek gaat naar iedereen die mag meebieden. Precies één partij wint, de rest verliest en houdt de data. Een partij hoeft de plek dus niet te winnen om je gegevens te krijgen. Zie Je toestelprofiel is de hoofdmoot van wat een app verstuurt.
Voor een lichte app betekent dat het volgende: hij hoeft maar weinig advertenties te tonen om toch de hele koperskring te bedienen. Eén advertentieplek per sessie is genoeg om je toestelprofiel bij tientallen partijen te laten arriveren. Het aantal verzoeken op je teller blijft laag, het bereik van je profiel is dat niet.
Waarom weinig verkeer juist misleidt¶
Hier zit de menselijke kant van deze notitie. Een lichte app wekt vertrouwen, en dat vertrouwen is een meetfout.
Je hebt geen kaartje in beeld, dus je denkt dat er geen locatie vertrekt. Je ziet nauwelijks reclame, dus je denkt dat er geen veiling loopt. Je merkt geen vertraging, dus je denkt dat er geen keten hangt. Al die redeneringen leiden van iets zichtbaars naar iets onzichtbaars, en dat is precies de sprong die deze markt zo hardnekkig maakt.
De constructie is zo gebouwd dat ze onzichtbaar blijft. De SDK draait op de achtergrond, vaak op het moment dat de app toch al locatie mag gebruiken voor zijn zichtbare functie. Het toestel vraagt één keer toestemming, de gebruiker geeft die voor het kaartje of het weer, en dezelfde toestemming dekt de stille stroom naar de broker mee af.
Er is ook geen scherm dat het verschil toont. De keuze die de gebruiker denkt te maken, gaat over de app. De stroom die hij niet ziet, gaat naar de broker.
Wat een naam in een lijst wel en niet bewijst¶
Hier moet ik streng zijn tegen mijn eigen bevinding, want deze notitie is makkelijk te ver door te trekken.
Een app die in een gelekte brokerlijst staat, is een sterk signaal en een reden om beter te kijken. Het bewijst op zichzelf niet dat er in jouw sessie ook echt data is verzonden. Een SDK kan aanwezig zijn en toch stil blijven, bijvoorbeeld omdat de gebruiker geen locatietoestemming gaf of omdat een scherm dat de SDK activeert nooit werd geopend. Zie Een naam in de code is nog geen tracker.
Het omgekeerde geldt net zo goed. Een app kan schoon lijken in een statische scan en pas onder gebruik gaan zenden. Meet je één seconde, dan meet je te weinig. Zie Niet alles vuurt bij opstart, sommige trackers wachten op jou en Meet zoals een bezoeker, niet zoals een scanner.
En een lijst kan verouderd zijn. Een gelekte brokerlijst is een momentopname uit het verleden. Een app die er destijds in stond, kan de SDK sindsdien hebben verwijderd. De juiste formulering is dus altijd: deze app stond op dat moment in die lijst. De formulering "deze app verkoopt je locatie" is van een andere orde en vraagt om een tweede meting. Het eerste is een vindplaats, het tweede is een beschuldiging.
Diezelfde discipline geldt aan de kant van de ketenbestanden. Een naam in ads.txt betekent dat een systeem de ruimte mág verhandelen. Dat is iets anders dan een waargenomen stroom. Zie Een advertentiesysteem mag meeverkopen zonder ooit een bod te doen en Label elke bevinding op bewijsniveau.
Waar mijn meting ophoudt¶
De ov-app is één geval, en ik heb er één procent advertentieverkeer aan gemeten en één vermelding in één gelekte lijst. Ik kan uit dat ene geval geen percentage voor de hele markt afleiden, en dat doe ik dus ook niet.
Wat het geval wel doet, is een aanname breken. Wie de vraag "is deze app veilig" beantwoordt met een verkeersteller, heeft één van de twee vragen beantwoord en denkt dat hij er twee heeft gedaan.
Van de andere kant loop ik tegen dezelfde muur als altijd. Waar de data van een broker uiteindelijk belandt, tot en met overheden, steunt op wat publiek over deze partijen bekend is en op het patroon dat de index blootlegt. Ik heb de aanwezigheid van de SDK gemeten, en de rest gelezen in openbaar materiaal (de-locatiedatahandel-heeft-vaste-spelers in mick_bodies.py).
Er bestaat ook een derde uitkomst die makkelijk verward wordt met een schone app: een mislukte meting. Certificaat-pinning laat de app zijn eigen servers gewoon bereiken terwijl mijn opname leeg blijft. Een lege lijst bij een app die normaal functioneert, is eerder een reden tot argwaan dan tot geruststelling. Zie Een mislukte meting is geen schone app.
Het tegenvoorbeeld bestaat wel¶
Om te voorkomen dat dit stuk elke app verdacht maakt: er zijn apps die het goed doen, en ik heb ze gemeten.
Een onderzochte cyclus-app had geen internet-permissie, een lokale database en geen actief netwerkpad in de code (GROND bij een-app-zonder-internet-permissie-is-echt-privacy). Die kán per definitie niet in een brokerlijst staan, want er vertrekt niets. In dezelfde reeks zat een app die nul netwerkverkeer maakte tijdens gewoon gebruik. Zie Geen internet-permissie, geen probleem en Een app kan volledig lokaal, zonder een enkele netwerkcall.
Tegelijk kan een oprechte maatregel naast een lek bestaan. Flo bouwt een echte beschermlaag, een anonieme modus via versleutelde doorgifte, live bevestigd, en heeft tegelijk de code van Meta, TikTok, AppsFlyer en Google aan boord (GROND bij een-oprechte-privacymaatregel-en-een-lek-bestaan-naast-elkaar). Die twee dingen staan naast elkaar, en een eerlijk oordeel noemt ze allebei. Zie Cyclus-apps weten het intiemste dat er is en Ontvangen is niet doorverkopen.
Wat je hier morgen mee doet¶
Als gebruiker, in tien minuten. Loop de locatiepermissies van al je apps langs, op Android onder Instellingen, Locatie, App-locatietoegang, op iOS onder Privacy, Locatievoorzieningen. Zet alles wat je positie niet echt nodig heeft op Nooit, en de rest op Alleen tijdens gebruik. Dat is de enige knop die de SDK-route onderbreekt, want de SDK leunt op de permissie die jij aan de app gaf.
Beoordeel apps daarna niet op hoe licht ze aanvoelen. Kijk in de app-winkel bij het gegevensveiligheidslabel welke categorieën de app declareert, en let vooral op "Locatie, gedeeld met derden". Dat vinkje staat er ook bij apps die nauwelijks verkeer maken.
Als onderzoeker: houd twee sporen apart in je dossier. Spoor één is de verkeersmeting, met het aandeel verzoeken en bytes. Spoor twee is de SDK-inventaris uit de APK, gelegd naast de bekende brokerlijsten. Trek pas een conclusie over de app als je beide sporen hebt, en label per spoor het bewijsniveau. Een app die op spoor één schoon is en op spoor twee raak, is de interessantste bevinding die je die dag hebt.
En als je een app bouwt: open je build.gradle en je afhankelijkhedenlijst, en zoek per SDK op wie de maker is en waar die zijn geld verdient. Een gratis SDK van een partij zonder zichtbaar verdienmodel wordt betaald met de gegevens van je gebruikers. Die rekening staat op jouw naam, want jij bent de verwerkingsverantwoordelijke.
- Mick Beer, "Wat Clue, Flo en Clover met je cyclusdata doen"een app die zelf niets verstuurt en toch in een handelslijst staat