Come proteggere un'app per Android

introduzione

Il sistema operativo Android ha molte funzioni di sicurezza integrate, come sandboxing delle applicazioni, protezione da attacchi di overflow del buffer e di interi e aree di memoria segregate per istruzioni e dati del programma. Di conseguenza, le semplici app Android che non eseguono operazioni su file system o di rete possono spesso essere considerate sicure per impostazione predefinita.

Se stai sviluppando un'applicazione più complessa, tuttavia, è tua responsabilità renderla protetta e proteggere la privacy dei tuoi utenti. In questo articolo, elencherò alcune delle migliori pratiche che è possibile seguire per creare un'app per Android sicura che non presenti perdite di dati o autorizzazioni ed è, in generale, meno vulnerabile alle app dannose che potrebbero essere installate sul dispositivo dell'utente.

1. Utilizzare la memoria interna per i dati sensibili

Ad ogni app Android è associata una directory di archiviazione interna il cui percorso è basato sul nome del pacchetto dell'app. I file all'interno di questa directory sono molto sicuri perché usano MODE_PRIVATE modalità di creazione del file per impostazione predefinita. Ciò significa che non è possibile accedere ai file da qualsiasi altra app sul dispositivo. Pertanto, è il posto migliore dove archiviare tutti i dati sensibili della tua app nella directory di archiviazione interna.

Per determinare il percorso assoluto della directory di archiviazione interna della tua app, ti consigliamo di utilizzare getFilesDir () metodo. Una volta che conosci il suo percorso, fare riferimento ai file al suo interno è semplice come fare riferimento a file all'interno di qualsiasi altra directory. Ad esempio, ecco come puoi fare riferimento a un file chiamato myfile.dat nella directory di archiviazione interna della tua app:

File myFile = new File (getFilesDir (), "myfile.dat");

2. Crittografa dati su memoria esterna

La capacità di archiviazione interna di un dispositivo Android è spesso limitata. Pertanto, a volte, non è possibile scegliere di memorizzare i dati riservati su supporti di memorizzazione esterni, ad esempio una scheda SD rimovibile.

Poiché i dati su supporti di archiviazione esterni possono essere direttamente accessibili sia dagli utenti sia da altre app sul dispositivo, è importante archiviarli in un formato crittografato. Uno degli algoritmi di crittografia più utilizzati oggi dagli sviluppatori è AES, abbreviazione di Advanced Encryption Standard, con una dimensione della chiave di 256 bit.

Scrittura del codice per crittografare e decrittografare i dati della tua app utilizzando javax.crypto il pacchetto, incluso nell'SDK di Android, può essere fonte di confusione. Pertanto, la maggior parte degli sviluppatori preferisce utilizzare librerie di terze parti, come la libreria Conceal di Facebook, che di solito sono molto più facili da utilizzare.

3. Usa Intenti per IPC

I programmatori esperti che sono nuovi nello sviluppo di applicazioni Android spesso tentano di utilizzare socket, named pipe o file condivisi per comunicare in modo asincrono con altre app installate su un dispositivo Android. Questi approcci non sono solo difficili ed ineleganti, ma anche soggetti a minacce. Un approccio più semplice e sicuro per interpretare la comunicazione sul sistema operativo Android è usare le intenzioni.

Per inviare dati a un componente specifico di un'app, è necessario creare una nuova istanza di Intento classe e usa il suo setComponent () metodo per specificare sia il nome del pacchetto dell'app che il nome del componente. È quindi possibile aggiungere dati ad esso utilizzando il putExtra () metodo.

Ad esempio, ecco come è possibile inviare la stringa Ciao mondo ad Attività chiamato MyActivity, che appartiene a un'app di cui è il nome del pacchetto my.other.app:

// Crea un intent Intent intent = new Intent (); // Specifica il nome del componente intent.setComponent (new ComponentName ("my.other.app", "my.other.app.MyActivity")); // Aggiungi data intent.putExtra ("DATA", "Hello World!"); // Invia l'intento all'attività startActivity (intent);

Per inviare dati a più app contemporaneamente, è possibile inviare l'intento come una trasmissione utilizzando il sendBroadcast () metodo. Tuttavia, per impostazione predefinita, una trasmissione può essere letta da qualsiasi app configurata in modo appropriato BroadcastReceiver.

Pertanto, se si desidera inviare informazioni sensibili come trasmissione, è necessario utilizzare un'autorizzazione personalizzata di cui ProtectionLevel è impostato per firma. In questo modo, il sistema operativo Android si assicura che solo le app che sono state firmate utilizzando la chiave di firma possano ricevere la trasmissione.

Ecco uno snippet di codice che mostra come inviare la stringa Ciao mondo come trasmissione sicura:

// Crea un intent Intent intent = new Intent (); // Aggiungi data intent.putExtra ("DATA", "Hello World"); // Specifica un nome di azione per // intento-filtro del destinatario intent.setAction ("my.app.receive"); // Invia come trasmissione utilizzando un'autorizzazione personalizzata sendBroadcast (intent, "my.custom.permission");

Si noti che il codice sopra riportato funziona come previsto solo se l'autorizzazione personalizzata viene dichiarata e utilizzata nei file manifest di entrambe le app del mittente e del destinatario.

 

4. Usa HTTPS

Tutte le comunicazioni tra la tua app e i tuoi server devono essere su una connessione HTTPS, preferibilmente utilizzando il HttpsURLConnection classe. Se pensi che l'uso di HTTP per i dati non riservati sia soddisfacente, ripensateci.

Molti utenti Android si collegano a diversi hotspot Wi-Fi aperti nelle aree pubbliche ogni giorno. Alcuni di questi hotspot potrebbero essere dannosi. Un hotspot dannoso può facilmente alterare il contenuto del traffico HTTP per far sì che l'app si comporti in modo inatteso o, peggio ancora, per iniettare annunci o exploit in esso.

Utilizzando HTTPS, fino a quando il server è configurato con un certificato rilasciato da un'autorità di certificazione attendibile, come DigiCert o GlobalSign, puoi essere sicuro che il tuo traffico di rete è sicuro contro attacchi di tipo "eavesdropping" e "man-in-the-middle".

Se la tua app ha un sacco di codice di rete e hai paura che potresti involontariamente inviare alcuni dati come testo in chiaro, dovresti prendere in considerazione l'uso di nogotofail, uno strumento open source creato da Google per trovare tali errori.

5. Usa GCM invece di SMS

Quando GCM, abbreviazione di Google Cloud Messaging, non esisteva, molti sviluppatori utilizzavano gli SMS per inviare i dati dai loro server alle loro app. Oggi questa pratica è in gran parte sparita.

Se sei uno di quegli sviluppatori che non ha ancora effettuato il passaggio da SMS a GCM, è necessario sapere che il protocollo SMS non è crittografato né sicuro contro gli attacchi di spoofing. Inoltre, un SMS può essere letto da qualsiasi app sul dispositivo dell'utente che ha il READ_SMS autorizzazione.

GCM è molto più sicuro ed è il modo preferito per inviare messaggi a un'app perché tutte le comunicazioni GCM sono crittografate. Sono autenticati utilizzando i token di registrazione regolarmente aggiornati sul lato client e una chiave API unica sul lato server. Per ulteriori informazioni su GCM, puoi fare riferimento a questo tutorial sulle notifiche push.

6. Evitare di chiedere dati personali

In questi giorni la privacy degli utenti è molto importante. Esistono infatti leggi, come la direttiva sulla protezione dei dati dell'Unione europea e la legge canadese sulla protezione dei dati personali e sui documenti elettronici, che impongono la protezione della vita privata di un utente. Pertanto, a meno che tu non abbia una buona ragione e un'infrastruttura molto sicura per raccogliere, archiviare e trasmettere informazioni personali dell'utente, devi evitare di richiederlo direttamente nelle tue app.

Un approccio migliore all'autenticazione degli utenti e alle informazioni del profilo utente visualizzate su Android avviene tramite la piattaforma Google Identity. Google Identity Platform consente agli utenti di accedere rapidamente alla tua app utilizzando il proprio account Google. Dopo aver eseguito correttamente l'accesso attraverso la piattaforma, ogni volta che è necessario, l'app può facilmente cercare vari dettagli sull'utente, come il nome dell'utente, l'indirizzo e-mail, la foto del profilo, i contatti e altro. In alternativa, puoi utilizzare servizi gratuiti come Firebase in grado di gestire l'autenticazione dell'utente per te.

Se è necessario gestire personalmente le credenziali dell'utente, si consiglia di archiviarle e trasmetterle sotto forma di hash protetti. Il modo più semplice per generare diversi tipi di hash utilizzando l'SDK di Android consiste nell'utilizzare il MessageDigest classe.

Ecco un piccolo frammento di codice che mostra come creare un hash della stringa Ciao mondo usando la funzione di hashing SHA-256:

// Inizializza MessageDigest per utilizzare SHA-256 MessageDigest md = MessageDigest.getInstance ("SHA-256"); // Converti la stringa in un byte hash [] sha256Hash = md.digest ("Hello World" .getBytes ());

7. Convalida l'input dell'utente

Su Android, l'input dell'utente non valido di solito non porta a problemi di sicurezza come il sovraccarico del buffer. Tuttavia, se si consente agli utenti di interagire con un database SQLite o un provider di contenuti che utilizza internamente un database SQLite, è necessario disinfettare rigorosamente l'input dell'utente o utilizzare query parametrizzate. In caso contrario, i dati saranno vulnerabili agli attacchi di SQL injection.

In una nota simile, la convalida dell'input dell'utente e la disinfezione sono anche molto importanti se si utilizza l'input dell'utente per generare dinamicamente codice da eseguire su un motore di scripting incorporato, come Mozilla Rhino.

8. Utilizzare ProGuard prima della pubblicazione

Le misure di sicurezza integrate in un'app Android possono essere gravemente compromesse se gli hacker sono in grado di mettere le mani sul codice sorgente. Prima di pubblicare la tua app, si consiglia di utilizzare uno strumento chiamato ProGuard, incluso nell'SDK di Android, per offuscare e minimizzare il codice sorgente.

Android Studio include automaticamente ProGuard nel processo di compilazione se buildtype è impostato per pubblicazione. La configurazione ProGuard predefinita disponibile nell'SDK di Android Proguard-android.txt il file è sufficiente per la maggior parte delle app. Se si desidera aggiungere regole personalizzate alla configurazione, è possibile farlo all'interno di un file denominato proguard-rules.pro, che è una parte di ogni progetto di Android Studio.

Conclusione

Spero che ora abbia una migliore comprensione di come rendere sicure le tue app Android. La maggior parte delle best practice che ho menzionato in questo articolo sono applicabili solo se stai utilizzando l'SDK di Android per sviluppare le tue app. Se stai utilizzando l'NDK di Android, devi stare molto più attento perché, mentre si programma in linguaggio C, ci si aspetta che tu gestisca dettagli di basso livello, come i puntatori e l'allocazione della memoria te stesso.

Per ulteriori informazioni sulla sicurezza su Android, è possibile fare riferimento ai documenti di sicurezza AOSP.