A seguito del rilascio del codice sorgente dell’app Immuni, abbiamo compilato l’app su O.S. Android. Tuttavia, dopo la fase di setting (permessi, provincia di residenza, informative) l’app non si attiva (poiché l’utilizzo dell API di Apple e Google è riservato alle entità governative e ai dev approvati).
Abbiamo quindi analizzato il codice, ponendo particolare attenzione alle comunicazioni dell’app verso l’esterno, ai dati che richiede e come funzionerà l’OTP; posto che come già detto da alcuni abbiamo per ora solo il codice dell’app, ma non i codici del server e quelli del backend usato per validare i codici (che sarà gestito dal ministero della Salute).
Un primo giudizio sul codice dell’app Immuni
E’ doveroso premettere che questo articolo richiede una conoscenza propedeutica del funzionamento delle API di Google ed Apple, di cui abbiamo già ampiamente parlato prima qui e poi qui. La nostra analisi si incastra in un percorso che ha accompagnato il lettore verso una conoscenza approfondita del reale funzionamento delle app di tracciamento, con un occhio rivolto alla tutela dei dati personali e all’impatto che l’app potrà avere sui diritti e sulle libertà della persona.
Non può negarsi che, già da una prima analisi, il software appare ben fatto, chiaro, ben stratificato e anche molto corposo. Del resto Bending Spoons non è l’ultima arrivata, anzi, è tra i leader del settore app mobile.
Molte informative atte a convincere e rassicurare l’utente
Sin da subito si nota che particolare attenzione è stata data alla comunicazione. Una lunga serie di informative mirate a “convincere” l’utente indeciso.
Infatti, l’esperienza di Singapore ci insegna che solo il 50% degli utenti che avevano scaricato l’app l’hanno poi effettivamente attivata. Da qui l’evidente necessità di proseguire nel processo decisionale dell’utente, dando per scontato che il punto di arrivo non sia il download, ma l’attivazione.
E allora ci ritroviamo declarations del tipo:
“Immuni non raccoglie il tuo nome, cognome, data di nascita, indirizzo, numero di telefono o e-mail. Immuni non può risalire alla tua identità o quella delle persone con cui entri in contatto.
Immuni non raccoglie alcun dato di geolocalizzazione, inclusi i dati del GPS. I tuoi spostamenti non sono tracciati in alcun modo. I dati salvati sul tuo smartphone e le connessioni al server sono cifrati.
I tuoi dati sono salvati sul server in Italia, sono gestiti da soggetti pubblici e controllati dal ministero della salute. Tutti i dati vengono eliminati quando non più necessari e, in ogni caso, non più tardi del 31 dicembre 2020
Per aiutare il Servizio Sanitario nazionale a prendersi cura di te, Immuni invia al server del Ministero della Salute la tua provincia di domicilio, l’avviso del corretto funzionamento dell’app, nonché i dati di esposizione precedenti”.
Analisi delle chiamate dell’app verso il server
Un momento…I dati di esposizione precedenti?
Quest’ultima dichiarazione ci fa drizzare le orecchie. Quindi Immuni avvertirà il server anche di chi ha ricevuto la notifica? Sembrerebbe un discostamento rispetto alle linee guida del classico DP3T a cui si ispira il sistema ipotizzato da Apple e Google.
Analizziamo a questo punto, codice alla mano, tutte le chiamate che Immuni fa verso il server (non quelle di Google ed Apple, sia chiaro), al fine di scoprire quali dati viaggiano verso il cloud e cosa portano via dallo smartphone.
L’API principale, relativa alla comunicazione con il server della dichiarata positività, è “/v1/ingestion/upload”. Questa API carica le Keys per autodiagnosi sul server, accompagnandole con i dati relativi alla provincia e (attenzione) anche con eventuali report di esposizione precedenti (ovvero i report di esposizione ricevuti).
Il report fatto dall’app sull’utente infetto
In altri termini, possiamo chiarire e sintetizzare così:
Se io risulto infetto e se in passato ho ricevuto avvisi di esposizione, viene generato un report, ovviamente anonimo e senza codici, composto da data, durata (a step di 5 minuti fino a 30 minuti) e intensità (del segnale) di ogni esposizione ad altre Keys risultate infette. Se il livello complessivo di rischio che viene fuori da questo report è elevato, viene generata la notifica di avviso. In ogni caso viene conservato per 14 giorni per poi essere appunto inviato nel caso in cui io stesso risultassi positivo.
Questo report dovrebbe essere raccolto dal server solo a fini statistici. Immaginiamo che l’interesse dell’app sia quello di capire la densità del focolaio e quanto e come i cittadini reagiscono alle notifiche.
Tra le API lato server c’è anche quella utilizzata per verificare l’OTP.
La procedura per l’upload dei codici sul server sanitario
Prima di analizzarla, andiamo a verificare come funzionerà, in effetti, il sistema necessario per autorizzare l’infetto a dichiararsi tale, al fine di avvertire chi è stato in contatto con lui.
Attivando quindi la procedura per consentire l’upload di tutti i codici con cui sono stato visibile in giro per la città (tecnicamente verranno inviate le Tracking Exposure Keys dei precedenti 14 giorni, che sono la matrice dei proximity ID che vengono sparati fuori tramite il bluetooth), l’app genera un codice casuale in locale. Nessun riferimento al telefono o al Device ID o alla Device Tracing Key.
L’app pesca lettere dell’alfabeto e si rigenera ad ogni avvio di app.
Il sanitario lo immette nel sistema tramite un tool specifico che verrà concesso alle strutture e, a quel punto, l’app con un tasto effettuerà la contro-verifica.
Il matching sul server restituirà un token che poi verrà utilizzato per autorizzare l’upload delle Keys.
E’ l’ora di verificare, quindi, l’API per la generazione del Token.
Generazione token per l’upload e sicurezza
Il suo nome è “/v1/ingestion/check-otp” e ha il solo scopo di verificare che l’OTP generato dal server sia stato verificato.
L’OTP è criptato con con algoritmo sha256 ed è accompagnato da un boolean che va settato a “true” se si tratta di un invio fake, utilizzato per depistare eventuali sniff del traffico.
Ciò consente un ulteriore grado di sicurezza all’intero protocollo.
La comunicazione infatti è in https, quindi il contenuto a prescindere è offuscato e non è facile capire (sniffando) se si tratta di upload fake.
Il server verifica che sia stato autorizzato (dal sanitario) e restituisce il token che viene poi utilizzato per poi fare l’upload.
Ad oggi, non avendo ancora il codice sorgente del server non possiamo sapere altro.
In ogni caso, tutto verrà criptato con sha256.
A proposito di ciò, ci piace far notare che al server non arriva l’OTP in chiaro, ma solo il suo hash.
Il server verifica che questo suo hash sia stato “verificato” (in precedenza dal sanitario) e dà l’ok. Dall’hash non si può tornare indietro all’OTP.
La notifica sarà molto semplice. Il messaggio che si legge nel codice sorgente è: un utente con cui sei entrato in contatto è risultato positivo al COVID-19. Scopri subito cosa devi fare.
Aprendo l’app invece appare un’immagine come la sottostante.
Ma la nostra analisi non è finita qui. Siamo andati oltre, sapendo che informazioni su “dove e quando” si è stati in contatto con l’infetto vengono comunque archiviate nell’app (sebbene in formato anonimo).
Una sbavatura privacy: si sa quando è avvenuto il contagio
Volevamo essere sicuri che fosse stato adottato un sistema secondo cui un utente non deve poter conoscere “quando” e con che intensità ha incontrato il positivo. In tal caso, pur senza parlare di tutela dei dati personali ai sensi del GDPR, l’app potrebbe avere comunque un impatto importante sulla società, considerando che un’informazione del genere restringerebbe di molto il campo di probabilità, consentendo di individuare (o di ipotizzare) l’identità del positivo. La caccia all’untore dev’essere assolutamente evitata.
E, purtroppo, abbiamo trovato una schermata (speriamo work in progress) che, allo stato attuale, consente di accedere a questa inutile informazione da parte dell’utente.
In sostanza l’utente potrà sapere “quando” è avvenuto il contagio e, con una buona dose di memoria e di deduzione, potrebbe essere in grado di risalire a “chi” si è denunciato come infetto. Con buona pace di ogni discorso sulla privacy. Privacy sostanziale, non normativa.Quando l’app entra in modalità “possibile contatto a rischio” nella pagina principale ci mostra una schermata dove si legge chiaramente “Immuni ha rilevato che due giorni fa hai avuto l’ultimo contatto con un utente positivo al COVID-19”.
Screenshot a parte, cosa c’è di effettivo all’interno del codice, che comanda questa funzione?
Analizzandolo, abbiamo trovato una funzione che calcola i giorni trascorsi dall’ultimo contatto con il soggetto a rischio.
Tuttavia, ad onor del vero, questa funzione non viene richiamata in quel messaggio, tant’è che la stringa di testo citata sopra, sembra non venga modificata mai e resti sempre su “2 giorni fa”. Sembrerebbe un work in progress (o un errore). Attendiamo lumi su una questione così importante.
Il download delle chiavi degli infetti
Un’altra chiamata è quella che richiede al server il download giornaliero delle diagnosis Keys, delle nuove chiavi dei pazienti risultati positivi al covid-19, allo scopo di fare il matching con quelle salvate nel proprio sistema operativo.
L’aggiornamento al momento è impostato su un timing di 2 ore (ma rileviamo un commento “//fixme”, quindi probabilmente sarà oggetto di ritocco). Per completezza espositiva al server vengono richiesti i settings (tramite la chiamata “v1/settings”) che vanno ad impostare questo timing e altre cose come il livello minimo di esposizione per far scattare la notifica.
Queste vengono scaricate tramite dei blocchi, dei “chunk”. Ogni chunk contiene un certo numero di nuove chiavi da dare in pasto alla libreria di A/G.
L’app tramite l’api “/v1/keys/index” verifica che ci siano nuovi chunk da scaricare rispetto all’ultimo aggiornamento effettuato. In caso di nuovi chunk disponibili, tramite l’api “/v1/keys/{chunkNumber}” viene scaricato un chunk e salvato in storage. I dati come sempre sono criptati e vengono dati in pasto alla libreria A/G senza che l’app legga o elabori il contenuto. Poi vengono cancellati.
Prima di concludere questa prima analisi sugli hot-topics dell’app (dati raccolti e comunicazioni), si è tanto parlato della necessità su android di attivare la geolocalizzazione.
In realtà la “geolocalizzazione” (solo su android) dev’essere attivata quando si vuole attivare il bluetooth. Lo richiede il framework di Google per qualsiasi app che effettua la scansione con dei Bluetooth vicini.
Gps attivato ma nessun dato usato
Android lo richiede poiché, scansionando con il Bluetooth, si potrebbero anche scansionare Beacon di edifici (es. negozi) geolocalizzati e quindi indirettamente – e teoricamente – reperire la posizione del telefono incrociando i dati.
Per questo motivo Google impone di tenere attiva la posizione mentre si utilizza questa funzione, per assicurarsi che l’utente sia conscio di questa possibilità, a prescindere dal fatto che l’app faccia o meno uso del sensore GPS. Si tratta, paradossalmente, di una garanzia per gli utenti, nei confronti di altre app che possono capire dove siamo in maniera indiretta. E, quindi, Immuni utilizzerà o meno i dati di GPS?
Anche in questo caso, torniamo al codice sorgente e leggiamo i permessi. Non serve un nerd, è davvero chiarissimo.
L’app chiede e utilizza solo due permessi di android: internet e bluetooth. Anche nel codice (oltre che nelle dichiarazioni), Immuni non accederà ad alcun dato di localizzazione. Ma era scontato.
In conclusione
In conclusione, sebbene il sistema sia ben strutturato sotto l’aspetto privacy-normativo, è necessario che questo lo si a anche sotto quello privacy-sostanziale.
Lasciare in chiaro il dato relativo alla data e all’ora del possibile contagio rappresenta il peggior approccio possibile. Paradossalmente sarebbe meno invasivo un sistema centralizzato che preveda anche una raccolta base di dati personali veri, piuttosto che un’app che preveda la visualizzazione di questa informazione.
Auspichiamo quindi una anonimizzazione dei dati relativi a “quando è avvenuto il contagio e con quale intensità”, anche perché questa informazione è assolutamente inutile. Una volta impostati i parametri per definire l’esposizione “a rischio contagio”, non sembra esserci alcuna necessità di dare ulteriori informazioni all’utente. Se si è deciso che per quel tipo di esposizione è necessario un test, non importa sapere quando e come. Siamo sicuri che si tratti di un “work in progress” e che questo aspetto verrà rivisto.
Detto ciò, abbiamo messo un altro tassello nella comprensione del sistema di tracciamento italiano. A questo punto manca solo il rilascio dei codici del server e quelli del backend per validare i codici, in uso agli operatori sanitari (oltre che il rilascio dei protocolli da seguire per questi ultimi).