HPKP: che cos'è il public key pinning per HTTP

La sicurezza dei canali per la trasmissione dei dati è un requisito importante nella comunicazione e nel lavoro digitali. Specialmente quando si inviano o ricevono pacchetti dati da remoto, o mentre non si è a casa o in ufficio, è fondamentale che l'intero percorso di trasmissione sia protetto: non a caso è prassi comune trasmettere informazioni riservate esclusivamente tramite VPN o connessioni SSL/TLS. Enti e aziende garantiscono la quasi inviolabilità di questi protocolli attraverso i propri server DNS e autorità di certificazione selezionate. Ma gli utenti che operano al di fuori di queste strutture sono soggetti alle gerarchie delle autorità certificative e dei DNS pubblici, il che aumenta la probabilità di un attacco man in the middle ai dati.

La causa principale dell'aumento del rischio legato alla sicurezza sono i certificati falsi emessi da autorità di certificazione dubbie o infiltrate. Paradossalmente questo significa che la sicurezza della connessione e dei dati potrebbe essere messa a repentaglio proprio da chi dovrebbe garantirla. Nel 2011 Google ha introdotto le cosiddette HTTP Public Key Pinning (HPKP), uno standard specificato nella RFC 7469.

HPKP: che cos'è?

Il Public Key Pinning è un'estensione del protocollo HTTP (Hypertext Transfer Protocol) che consente di specificare il set di chiavi pubbliche per le future connessioni SSL/TLS a un host. In questo modo un client apprende al primo tentativo di contatto quali sono le chiavi pubbliche sicure per connettersi a un determinato host. Si parla in questo senso di modello Trust on First Use (fiducia al primo utilizzo). Ogni voce di una chiave verificata viene chiamata pin, da cui il meccanismo prende il nome. Tutti i pin creati vengono trasmessi al client tramite l'header HTTP e quindi memorizzati per un determinato periodo.

Al momento di effettuare una nuova richiesta di connessione, il client verifica se la catena di certificazione per la trasmissione SSL/TLS contiene una chiave pubblica precedentemente ricevuta tramite HPKP. In caso negativo, ad esempio nella circostanza di un certificato falso, viene visualizzato un messaggio di errore e la connessione non viene stabilita. Questo processo di verifica si chiama anche convalida del pin. Le voci dei pin nell'header HTTP hanno grossomodo questo aspetto:

Public-Key-Pins:
  pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=";
  pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
  pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=";
  max-age=2592000; includeSubDomains; report-uri="http://example.com/pkp-report"

Questo esempio mostra tutte le quattro direttive che possono essere contenute da un pin nell'header HTTP:

  • pin: la direttiva pin è la parte più importante dell'iscrizione. È costituita da un nome e da un valore: il nome fornisce informazioni sull'algoritmo utilizzato per la crittografia – finora soltanto SHA256; il valore hash compreso tra le virgolette è una stringa codificata in Base64, nota anche come fingerprint. Per ogni chiave (inclusi i back-up), ogni pin deve avere una direttiva separata.
     
  • max-age: la direttiva max-age specifica in secondi il tempo durante il quale il pin è valido, comunicando al cliente quanto a lungo possa valutare sicura un'eccellente chiave pubblica. Nell'esempio utilizzato i pin listati vengono cancellati dopo 30 giorni (2.592.000 secondi).
     
  • includeSubDomains: l'indicazione includeSubDomains è opzionale e non richiede un valore. La sua funzione è di segnalare al client che le regole di certificazione specificate non valgono solo per il dominio, ma anche per tutti i sottodomini che appartengono all'host.
     
  • report-uri: se la direttiva report-uri è attivata, tutti i tentativi di convalida del pin non riusciti vengono inviati all'URL. Questo non deve necessariamente trovarsi sullo stesso dominio Internet dell'host contattato, che viene in questo modo informato dei tentativi di configurazione non riusciti.

Come funziona il certificate pinning sul proprio server?

Se volete sfruttare le possibilità dell'HPKP, dovete anzitutto decidere su quale chiave pubblica o quali chiavi pubbliche eseguire il pinning. In linea di principio potete scegliere qualsiasi chiave pubblica contenuta nella catena dei certificati: può quindi trattarsi di un certificato root, server o intermedio. Se scegliete autorità di certificazione esterne, tenete presente che tutti i certificati emessi da tali autorità verranno sempre considerati validi dai client e condurranno alla convalida del pin.

Se avete sottoposto a pinning la vostra chiave server, sarebbe particolarmente grave perderla o non poterla utilizzare a causa di un problema di hardware. Infatti i client, dal momento che hanno salvato il pin e lo considerano valido per il tempo specificato al primo accesso, non accetterebbero un nuovo pin prima della scadenza definita. Questo vuol dire che gli utenti non sarebbero più in grado di accedere al server. Per evitare uno scenario di questo tipo, lo standard HPKP (RFC 7569) prevede un pin aggiuntivo di back-up, che viene fornito anche nell'header HTTP e può essere utilizzato per il rilascio di un nuovo certificato in caso di emergenza. Questo processo è chiamato Certificate Signing Request (CSR).

Consiglio

Browser come Mozilla Firefox e Google Chrome seguono lo standard RFC 7469 e quindi ignorano gli header HPKP o mostrano messaggi di errore nel caso sia impostato un solo pin. Per un supporto ottimale della HPKP da parte del browser bisogna sempre specificare almeno due chiavi pubbliche valide o un pin di back-up per la convalida del pin.

Calcolare i pin delle chiavi pubbliche

La configurazione dell'HTTPS è una condizione necessaria per il funzionamento dell'HPKP sul vostro server. Poiché almeno due chiavi pubbliche devono essere "pinnate", il primo passo è la generazione di questi pin. La semplice soluzione per calcolare i valori hash delle chiavi pubbliche esistenti è l'applicazione open source openssl, utilizzabile tramite la riga di comando del proprio sistema. L'RFC 7469 stabilisce il seguente comando standard per i certificati X.509:

openssl x509 -noout -in certificate.pem -pubkey | \
  openssl asn1parse -noout -inform pem -out public.key
openssl dgst -sha256 -binary public.key | openssl enc -base64

In questo modo, nel caso del certificato di esempio certificate.pem, create la sequenza Base64 per la chiave public.key. Questa viene emessa in forma standard e termina sempre con il segno uguale ("=").

Il passaggio successivo consiste nell'impostazione della Certificate Signing Request (qui: backup.csr) per la vostra chiave di back-up (qui: backup.key):

openssl genrsa -out backup.key 2048
openssl req -new -key backup.key -out backup.csr

Con l'aiuto di openssl calcolate infine anche il valore hash di questa chiave:

openssl req -noout -in backup.csr -pubkey | \
  openssl asn1parse -noout -inform pem -out backup.key
openssl dgst -sha256 -binary backup.key | openssl enc -base64

Protezione dei pin di back-up

Poiché la chiave di back-up HPKP sostituisce quella standard in caso di bisogno, è opportuno salvarla separatamente. La soluzione migliore è quella di utilizzare una piattaforma di archiviazione esterna che sia raggiungibile sempre e da qualunque luogo. Altrettanto raccomandabile è l'impiego di un password manager: proteggendo il CSR e la chiave corrispondente nella vostra banca dati tramite un software di questo tipo, potete sentirvi al sicuro e avere la chiave di back-up pronta all'uso in qualsiasi momento.

Critiche al public key pinning

Il modello Trust on First Use, come detto sopra, prevede che l'HPKP entri in effetto subito dopo il primo contatto del client. Questo significa che la prima visita, nel corso della quale il server trasmette le chiavi, non gode della protezione di questa procedura. Sebbene questo piccolo gap possa causare degli inconvenienti in casi isolati, di fatto non correte un gran rischio di subire un attacco alle connessioni SSL/TLS del vostro sito. La critica principale che viene mossa nei confronti del public key pinning riguarda uno scenario in particolare, reso possibile proprio dall'impiego della tecnica del pinning ed esemplificato come segue:

  1. Un aggressore vuole attaccare il vostro sito e ottiene l'accesso al server.
  2. L'aggressore installa un nuovo certificato SSL/TLS e crea il proprio paio di chiavi.
  3. L'aggressore genera il valore hash appropriato per la chiave pubblica e lo inserisce al posto del vostro pin nell'area corrispondente dell'header del certificato pinnato.
  4. Gli utenti e i client che entrano in contatto con il vostro sito per la prima volta ottengono in questo modo il pin sbagliato e non sono più in grado di stabilire una connessione sicura con il vostro server.
  5. Se l'aggressore cancella di nuovo il certificato dal vostro server, a questi utenti continuerà a essere impedito l'accesso per tutto il periodo di validità del pin sbagliato.
  6. Oltre ai danni inflitti dalla perdita di traffico, l'aggressore in teoria ha anche la possibilità di ricattarvi chiedendovi del denaro per lo sblocco del certificato falso.

Anche se questo scenario è in teoria possibile, non è certamente un valido argomento contro l'HTTP Public Key Pinning: infatti l'aggressore potrebbe comunque impostare da solo l'estensione del protocollo HTTP, non appena ottenuto l'accesso al server. Il punto fondamentale resta l'importanza di proteggere il vostro sito dagli attacchi degli hacker. Se utilizzate i pin, dovreste anche fare in modo che il software di monitoraggio vi informi immediatamente delle modifiche alle intestazioni HPKP in modo da poter agire in tempo utile. Un'eventuale soluzione lato client potrebbe essere il meccanismo di reset dei pin che elimini regolarmente quelli maligni.

Altri punti critici riconosciuti sono la scarsa diffusione e la complessità di configurazione del public key pinning, dovute probabilmente al fatto che questo standard è poco conosciuto o non lo è affatto.