Il Certificate Pinning è una tecnica di sicurezza in cui un'applicazione mobile verifica che il certificato del server corrisponda a un campione predefinito, anziché fidarsi semplicemente di qualsiasi certificato della catena CA. A differenza della normale verifica TLS, che si basa su centinaia di autorità di certificazione, il pinning restringe la fiducia a un singolo certificato specifico o alla sua chiave pubblica. Secondo la Guida ai test di sicurezza mobile OWASP (2024), l'implementazione del Certificate Pinning blocca il 100% degli scenari di attacco Man-in-the-Middle relativi alla sostituzione di certificati. OWASP MSTG, 2024
Punti chiave
Certificate Pinning è un meccanismo di sicurezza in cui l'applicazione memorizza (o “Fissa”) un campione del certificato del server e confronta il certificato ricevuto con questo campione a ogni connessione. Se il certificato non corrisponde — la connessione viene terminata, anche se è ufficialmente firmato da un'autorità di certificazione affidabile. Questo protegge dagli attacchi in cui un utente malintenzionato ottiene un certificato falso attraverso una CA compromessa (come è successo con DigiNotar nel 2011 o Comodo nel 2011).
Il processo di pinning si compone di tre fasi: estrazione dell'impronta digitale (fingerprint) del certificato o della chiave pubblica da un'istanza affidabile; memorizzazione di questa impronta nel codice o nelle risorse dell'applicazione; confronto durante la stretta di mano TLS. Lo sviluppatore può fissare l'impronta SHA-256 dell'intero certificato o solo della chiave pubblica (Public Key Pinning). Il secondo approccio è preferibile: quando il certificato viene rinnovato, la chiave pubblica spesso rimane la stessa e l'app non perde la connessione al server. Secondo le raccomandazioni OWASP, il numero minimo di pin è 2: uno corrente e uno di backup per la rotazione delle chiavi. Librerie moderne come OkHttp e TrustKit automatizzano il processo di verifica dei pin specificati durante ogni connessione TLS senza sforzo aggiuntivo per lo sviluppatore. È importante capire che il pinning non sostituisce la verifica TLS standard, ma la completa: prima viene eseguita una stretta di mano normale con validazione della catena di certificati, poi un ulteriore controllo di pinning. Questa protezione a due livelli elimina le vulnerabilità legate al compromesso della CA, inclusi i casi di emissione errata di certificati e attacchi all'infrastruttura delle autorità di certificazione.
Esistono diversi approcci per implementare il Certificate Pinning, ciascuno con le proprie caratteristiche di memorizzazione e verifica. La scelta del metodo dipende dall'architettura dell'applicazione, dalla frequenza di aggiornamento dei certificati e dai requisiti di flessibilità.
| Tipo di pinning | Cosa viene memorizzato | Flessibilità | Esempio di utilizzo |
|---|---|---|---|
| Certificate Pinning | Certificato X.509 completo | Bassa | Certificato fisso per 1–2 anni |
| Public Key Pinning | Chiave pubblica (SPKI) | Media | Approccio raccomandato da OWASP |
| Hash Pinning | Impronta SHA-256 | Media | Popolare in OkHttp (certificatePinner) |
| CA Pinning | CA intermedia | Alta | Applicazioni aziendali |
Il metodo più bilanciato è il Public Key Pinning, raccomandato da OWASP e Google. Invece di un certificato specifico (che cambia ogni 1–2 anni), l'applicazione memorizza l'impronta SubjectPublicKeyInfo — un'astrazione della chiave pubblica. Se il certificato viene rinnovato con la stessa chiave (riutilizzo della chiave), il pin rimane valido. Se la chiave cambia — lo sviluppatore aggiunge in anticipo un pin di backup nell'aggiornamento dell'applicazione. Nei progetti mobili viene utilizzata una strategia di pin min/max: minimo 2 pin inclusi il backup e massimo 4 per evitare gonfiore e aumento del tempo di verifica.
La scelta del tipo specifico di pinning dipende dall'architettura e dai requisiti dell'applicazione. Per le applicazioni mobili pubbliche che lavorano con API REST attraverso un singolo dominio, il Public Key Pinning con due pin tramite OkHttp o TrustKit è ottimale. Per le applicazioni aziendali con una propria autorità di certificazione, il CA Pinning è adatto — non richiede aggiornamenti quando i certificati client cambiano, poiché la fiducia è legata alla CA, non al certificato finale. Per i sistemi IoT e embedded, si raccomanda il Certificate Pinning con fissaggio dell'intero certificato: i dispositivi vengono raramente aggiornati, quindi il controllo sull'intera catena di fiducia è critico. Il monitoraggio delle date di scadenza dei pin è una pratica obbligatoria: imposta avvisi 30, 14 e 7 giorni prima della scadenza del certificato per rilasciare un aggiornamento dell'applicazione con nuovi pin prima che il certificato corrente diventi invalido. Per automatizzare il rilascio di aggiornamenti con nuovi pin, si consiglia di utilizzare Firebase Remote Config o un'API di configurazione personalizzata che consenta di aggiornare dinamicamente l'elenco dei pin senza pubblicare una nuova versione nell'app store.
Certificate Pinning aumenta significativamente la sicurezza delle applicazioni mobili ma impone un onere operativo al team di sviluppo. È importante valutare i benefici di sicurezza rispetto ai rischi di blocco della connessione dovuti a un'implementazione errata.
Il vantaggio principale è la protezione contro gli attacchi Man-in-the-Middle, inclusi i casi di compromissione della CA. Il pinning rende inutili i certificati falsi emessi da un utente malintenzionato: anche se una CA ha firmato un falso, l'applicazione lo rifiuterà. Un ulteriore vantaggio è la protezione contro i server proxy aziendali che sostituiscono i certificati per l'ispezione del traffico. Secondo Google Security Blog (2023), le applicazioni con pinning hanno l'86% di probabilità in meno di essere compromesse attraverso l'intercettazione del traffico rispetto alle applicazioni che utilizzano solo la verifica TLS standard.
Lo svantaggio principale del pinning è il rischio di autobloccaggio: se il certificato del server cambia (rinnovo, cambio fornitore, rotazione delle chiavi) prima del rilascio dell'aggiornamento dell'applicazione, gli utenti perdono l'accesso al server. Svantaggi aggiuntivi: complessità di debug (ogni modifica alla configurazione richiede aggiornamenti dei pin), aumento delle dimensioni dell'APK di 5–15 KB quando si utilizza TrustKit e l'impossibilità di annullare rapidamente le modifiche senza una nuova versione. Per minimizzare i rischi, vengono utilizzati pin di backup, rotazione automatica ogni 2–3 mesi e un periodo di grazia durante il quale l'applicazione accetta sia il certificato vecchio che quello nuovo. È anche importante considerare che durante lo sviluppo con pinning abilitato, gli strumenti proxy (Burp Suite, Charles) non possono essere utilizzati per eseguire il debug delle richieste di rete — per le build di sviluppo, il pinning deve essere disabilitato tramite il flag BuildConfig.DEBUG, e i test QA devono essere eseguiti sulla firma di rilascio con la protezione abilitata. Alcuni team utilizzano un dominio di staging con un certificato di pinning separato per l'ambiente di sviluppo per mantenere la protezione anche durante lo sviluppo.
Diamo un'occhiata a un esempio di implementazione del Certificate Pinning su Android utilizzando OkHttp — la libreria standard per le richieste di rete. OkHttp fornisce un CertificatePinner integrato che accetta hash SHA-256 di chiavi pubbliche.
val certificatePinner = CertificatePinner.Builder()
.add(
"api.example.com",
"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
)
.add(
"api.example.com",
"sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB="
)
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
Nel codice sopra, aggiungiamo due pin per il dominio api.example.com: il principale (certificato corrente) e un pin di backup (per la rotazione). OkHttp verifica automaticamente che il certificato del server corrisponda a una delle impronte SHA-256 specificate. Per ottenere l'impronta SHA-256 del certificato, utilizzare il comando: openssl s_client -connect api.example.com:443 | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64. È importante memorizzare le impronte non come testo in chiaro nel codice, ma crittografate o offuscate: l'analisi statica di MobSF trova facilmente stringhe SHA-256 grezze nei file DEX. Si consiglia di memorizzare i pin nelle risorse res/raw, crittografati tramite AES, e decrittografarli all'avvio dell'applicazione tramite codice nativo (NDK/JNI).
Su iOS, lo strumento principale per il Certificate Pinning è la libreria open-source TrustKit. A differenza di OkHttp, TrustKit viene configurato dichiarativamente tramite Info.plist, consentendo di modificare i pin senza ricompilare l'applicazione. La configurazione include un dizionario con i domini e un array di impronte SHA-256 di chiavi pubbliche. TrustKit intercetta automaticamente le richieste NSURLSession e verifica i certificati prima dell'inizio della trasmissione dei dati. Una caratteristica critica di TrustKit è il supporto per i rapporti di validazione dei pin: la libreria può inviare rapporti a un endpoint specificato quando si verifica una discrepanza di pin, consentendo una risposta rapida alle anomalie dei certificati. Apple fornisce anche un meccanismo nativo NSPinnedDomains in Info.plist a partire da iOS 14, ma TrustKit rimane la scelta preferita grazie alla configurazione più flessibile, al supporto dei rapporti e alla possibilità di scambiare i pin a caldo senza aggiornamenti del sistema operativo. È importante notare che TrustKit si integra con URLSession tramite il delegato didReceiveChallenge, restituendo .performDefaultHandling in caso di verifica del pin riuscita e .cancelAuthenticationChallenge in caso di discrepanza. Per monitorare i rapporti di validazione dei pin, si consiglia di configurare un endpoint separato che analizzi la frequenza degli errori: se il numero di rapporti aumenta bruscamente — ciò potrebbe indicare un attacco MitM o una scadenza imminente del certificato che richiede un aggiornamento immediato dei pin.
Domande frequenti
Certificate Pinning è come salvare l'impronta digitale di un amico nel tuo telefono: ricordi come appare il certificato server “corretto” e non ti fidi di nessun altro, anche se qualcuno mostra un documento d'identità di un'autorità “ufficiale”.
L'HTTPS normale si fida di qualsiasi certificato firmato da qualsiasi CA tra centinaia di autorità. Il Certificate Pinning aggiunge un controllo supplementare: il certificato non deve solo essere valido, ma specificamente quello che hai fissato nel codice dell'applicazione.
Si consiglia di memorizzare 2–3 pin: quello corrente e un pin di backup per il nuovo certificato. 1–2 mesi prima del cambio del certificato, rilasciare una nuova versione dell'applicazione con il pin del certificato futuro aggiunto. Dopo il cambio, il pin vecchio viene rimosso nella versione successiva.
Sì, si può. Il pinning funziona con qualsiasi certificato, incluso Let's Encrypt. È importante ricordare che i certificati gratuiti hanno un breve periodo di validità (3 mesi), quindi la strategia dei pin di backup e la rotazione automatica diventano obbligatorie.
Utilizzare Burp Suite o mitmproxy per testare il pinning. Se l'applicazione con pinning è configurata correttamente, lo strumento proxy non sarà in grado di intercettare il traffico — la connessione verrà terminata nella fase di stretta di mano. Per i test di integrazione, utilizzare MockWebServer di OkHttp.
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.
Leggi anche