La sicurezza mobile è un insieme di misure per proteggere l'applicazione, i dati dell'utente e l'infrastruttura del server da attacchi e fughe di dati. Secondo OWASP Mobile Top 10 (2024), la memorizzazione non sicura dei dati rimane la vulnerabilità più comune nelle applicazioni mobili. In questo articolo analizzeremo le principali minacce, i metodi di crittografia, l'archiviazione sicura, l'autenticazione e la protezione del codice — tutto ciò che uno sviluppatore principiante deve sapere.
Punti Chiave
OWASP (Open Web Application Security Project) è un'organizzazione senza scopo di lucro che pubblica una classifica delle vulnerabilità di sicurezza mobile più pericolose. OWASP Mobile Top 10 è un elenco che aiuta gli sviluppatori a capire su cosa concentrarsi per primi. Nella versione 2024, i problemi relativi a memorizzazione non sicura, autenticazione debole e comunicazione di rete non sicura guidano la classifica.
M1: Memorizzazione Non Sicura dei Dati — il problema più comune: password, token e dati personali rimangono in SharedPreferences, NSUserDefaults o file locali senza crittografia. M2: Autenticazione Debole — mancanza di verifica lato server, password deboli. M3: Comunicazione di Rete Non Sicura — mancanza di HTTPS o verifica errata del certificato SSL. M4 e M5 sono relativi alla crittografia e all'uso improprio delle API.
M6: Autorizzazione Non Sicura — un utente può accedere ai dati di un altro utente sostituendo un ID in una richiesta. M7: Iniezione di Codice (SQL Injection, XSS). M8: Manipolazione dell'App — repackaging, sostituzione del codice. M9 e M10 — fuga di dati tramite librerie di terze parti e reverse engineering. Per ciascuna di queste minacce esistono contromisure comprovate, e in IT Sectr le applichiamo in tutti i progetti dal 2017.
L'attacco MITM si verifica quando un attaccante intercetta il traffico tra l'applicazione e il server. Ciò è possibile attraverso spoofing DNS, ARP spoofing o connessione a una rete Wi-Fi non protetta. Per la protezione vengono utilizzati certificati SSL/TLS e Certificate Pinning.
Certificate Pinning è un meccanismo in cui l'applicazione verifica che il certificato del server corrisponda a uno pre-memorizzato nel codice dell'applicazione. Anche se un attaccante sostituisce il certificato tramite un proxy (ad esempio Burp Suite), l'applicazione rifiuterà la connessione. Il Pinning è di due tipi: Public Key Pinning e Certificate Hash Pinning.
AES (Advanced Encryption Standard) è un algoritmo di crittografia simmetrica, il fondamento della sicurezza dei dati sul dispositivo. AES utilizza la stessa chiave per crittografare e decrittografare i dati. AES supporta chiavi da 128, 192 o 256 bit. Nello sviluppo mobile, AES-256 viene utilizzato per crittografare i dati sul dispositivo: file, cache, record nel database locale.
Modalità AES: GCM (raccomandata) — fornisce autenticazione dei dati, CBC — modalità base con concatenamento di blocchi, ECB — non sicura, non usarla. Per iOS, AES è disponibile tramite CommonCrypto (CCOptions), per Android — tramite Cipher in Java Cryptography Architecture (JCA). Importante: la chiave di crittografia non deve mai essere memorizzata nel codice dell'applicazione — usa Keychain/Keystore.
Crittografia Asimmetrica: RSA — utilizza una coppia di chiavi (pubblica e privata). RSA viene utilizzato per crittografare piccole quantità di dati — tipicamente per scambiare una chiave simmetrica tra client e server. La lunghezza minima della chiave RSA è di 2048 bit (4096 raccomandati). Su iOS, RSA è disponibile tramite Security Framework (SecKeyCreateRandomKey), su Android — tramite KeyPairGenerator in Android Keystore.
Hashing (SHA-256, SHA-3) è una trasformazione irreversibile dei dati in una stringa di lunghezza fissa. Gli hash vengono utilizzati per la verifica dell'integrità dei dati e l'archiviazione delle password. Per le password, usa obbligatoriamente bcrypt, scrypt o Argon2 — il semplice SHA-256 è vulnerabile agli attacchi con tabelle rainbow. SSL/TLS è un protocollo per crittografare il traffico di rete tra client e server. Lo standard moderno è TLS 1.3, che fornisce Perfect Forward Secrecy (PFS).
TLS 1.3 è più veloce dei suoi predecessori: l'handshake richiede un round trip invece di due. Su Android, la versione minima di TLS è configurata tramite SSLSocket, su iOS — tramite ATS (App Transport Security), che per impostazione predefinita richiede TLS 1.2 o superiore. ATS può essere disabilitato solo per domini specifici con giustificazione.
Keychain (Portachiavi) è un archivio sicuro in iOS / macOS per password, chiavi di crittografia, certificati e token. I dati in Keychain sono crittografati con una chiave hardware unica per ogni dispositivo. L'accesso a Keychain è controllato tramite Security Framework (SecItemAdd, SecItemCopyMatching). Keychain si blocca automaticamente quando il dispositivo viene bloccato ed è crittografato tramite Secure Enclave.
Android Keystore è un archivio di sistema per chiavi crittografiche, isolato dall'applicazione. A partire da Android 6.0 (API 23), Keystore utilizza il supporto hardware (TEE — Trusted Execution Environment) sui dispositivi con chip di sicurezza. Le chiavi in Keystore non lasciano mai l'area protetta — l'applicazione riceve solo un handle per le operazioni di crittografia e firma.
| Parametro | iOS Keychain | Android Keystore |
|---|---|---|
| Tipo di dati memorizzati | Password, token, chiavi, certificati | Chiavi crittografiche |
| Supporto hardware | Secure Enclave (tutti gli iPhone con A7+) | TEE (Android 6+, dipende dal chip) |
| Crittografia | AES-256 hardware | AES/GCM con chiave hardware |
| Biometria | Face ID / Touch ID per accesso | BiometricPrompt per accesso |
| iCloud / backup | Sincronizzazione tramite iCloud Keychain | Non si sincronizza con il cloud |
| Prestazioni | Più lento (crittografia hardware) | Più veloce (TEE) |
SharedPreferences e NSUserDefaults non sono progettati per memorizzare dati sensibili — memorizzano informazioni in chiaro. Per la protezione dei dati, usa EncryptedSharedPreferences (Android) o crittografa i dati prima di salvarli in UserDefaults (iOS). In IT Sectr, utilizziamo sempre Keychain e Keystore per i token di accesso e le password.
OAuth 2.0 è un protocollo di autorizzazione delegata che fornisce accesso sicuro alle risorse dell'utente senza trasmettere la password. Nelle applicazioni mobili, il flusso Authorization Code con PKCE (Proof Key for Code Exchange) è il più comunemente utilizzato. PKCE impedisce l'intercettazione del codice di autorizzazione — un requisito obbligatorio per le applicazioni mobili.
OpenID Connect (OIDC) è un'estensione sopra OAuth 2.0 per l'autenticazione dell'utente. OIDC aggiunge un ID Token in formato JWT che contiene le informazioni dell'utente (nome, email, id). Il flusso OAuth 2.0 + OIDC include: reindirizzamento dell'utente alla pagina di login, ottenimento di un codice di autorizzazione, scambio del codice per token (access + refresh + id), utilizzo del token di accesso per le richieste API.
JWT (JSON Web Token) è un formato di token compatto e sicuro per URL che contiene claim in formato JSON. JWT è composto da tre parti: header (tipo e algoritmo di firma), payload (dati) e signature (firma). L'Access Token è un token di breve durata (15–60 minuti) per l'accesso alle API. Il Refresh Token è un token di lunga durata (giorni/settimane) per ottenere un nuovo access token senza ripetere il login.
Session Token è un approccio tradizionale in cui il server memorizza la sessione in un database o Redis, e il cliente riceve un identificatore casuale. Nello sviluppo mobile, JWT è preferibile: non richiede memorizzazione della sessione lato server, contiene tutte le informazioni al suo interno ed è facile da verificare. Tuttavia, JWT non può essere revocato istantaneamente — questo è un compromesso che viene risolto con una breve durata dell'access token e l'uso di refresh token.
Face ID e Touch ID su iOS, Autenticazione tramite Impronta Digitale su Android — metodi di autenticazione biometrica che utilizzano caratteristiche fisiche uniche dell'utente. Su iOS, la biometria funziona tramite LocalAuthentication (LAContext), su Android — tramite BiometricPrompt (Android 9+) o FingerprintManager (obsoleto). La biometria viene utilizzata per sbloccare l'app, confermare pagamenti e accedere a dati protetti.
Sfumature importanti: la biometria è una UX comoda, ma non sostituisce l'autenticazione del server. Dopo una verifica biometrica riuscita, l'applicazione dovrebbe ottenere un access token dal server. Su Android, assicurati di verificare che il dispositivo utilizzi biometria di Classe 3 (Forte), non solo riconoscimento facciale basato su fotocamera (Classe 1).
ProGuard è uno strumento di offuscamento, compressione e ottimizzazione del bytecode Java per Android, che aumenta la sicurezza del codice contro il reverse engineering. R8 è il suo successore, integrato in Gradle da Android Studio 3.4. R8 esegue quattro attività: compressione (rimuove classi e metodi inutilizzati), ottimizzazione (inline i metodi, semplifica il codice), offuscamento (rinomina classi e metodi con nomi brevi) e pre-verifica (controllo del bytecode).
DexGuard è una versione commerciale di ProGuard con protezione avanzata: crittografia delle stringhe, offuscamento delle risorse, protezione dal repackaging, controllo dell'integrità APK. Per la maggior parte dei progetti, R8 è sufficiente, ma per applicazioni finanziarie e bancarie, DexGuard fornisce un ulteriore livello di sicurezza. R8 si attiva tramite build.gradle: minifyEnabled = true e proguardFiles.
Root Detection (Android) e Jailbreak Detection (iOS) sono meccanismi che verificano se sul dispositivo sono stati ottenuti privilegi di superutente. Su dispositivi compromessi, è possibile leggere la memoria del processo, intercettare il traffico e sostituire il codice. Per la verifica su Android, si utilizza la presenza del binario SU, chiavi di firma di test e flag di build non standard.
RASP (Runtime Application Self-Protection) è una tecnologia che protegge l'applicazione durante l'esecuzione. RASP rileva tentativi di debug, repackaging, iniezione di codice e termina l'applicazione quando vengono rilevate minacce. Esempi di soluzioni RASP: Dexter, Guardsquare, Promon. RASP funziona a runtime e reagisce alle anomalie — a differenza dell'offuscamento statico, che protegge il codice prima dell'esecuzione.
Reverse Engineering è il processo di recupero del codice sorgente da un'applicazione compilata. Strumenti: JADX (decompilatore APK), Ghidra, IDA Pro, Hopper. La protezione dal Reverse Engineering è una combinazione di offuscamento, crittografia delle stringhe, verifica dell'integrità e Root Detection. Non esiste protezione completa — l'obiettivo è rendere il reverse engineering sufficientemente costoso per l'attaccante.
Domande Frequenti
Inizia con OWASP Mobile Top 10 — è una roadmap delle vulnerabilità più comuni. Poi studia HTTPS e certificati SSL, configura Certificate Pinning e passa all'archiviazione sicura tramite Keychain / Keystore.
AES (simmetrica) — una chiave per crittografare e decrittografare, veloce, adatta a grandi volumi di dati. RSA (asimmetrica) — una coppia di chiavi (pubblica e privata), più lenta, utilizzata per scambiare la chiave simmetrica.
Devi crittografare solo i dati riservati: password, token, dati personali dell'utente, informazioni di pagamento. Immagini, testi e impostazioni dell'interfaccia non richiedono crittografia — questo aumenterebbe le dimensioni e rallenterebbe l'applicazione.
Refresh Token è un token di lunga durata che permette di ottenere un nuovo Access Token senza reinserire la password. Questo aumenta la sicurezza — l'Access Token vive 15–60 minuti, e anche se viene divulgato, l'attaccante non può usarlo a lungo.
Sì, R8 deve essere attivato per le build di release di Android. Non è solo protezione dal Reverse Engineering, ma anche riduzione delle dimensioni dell'APK e ottimizzazione delle prestazioni. Senza R8, il tuo codice può essere decompilato in forma leggibile con un singolo comando JADX.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.