mercoledì 22 aprile 2020

Defensive programming

Il 21 aprile ho tenuto un webinar sulla sicurezza. In particolare abbiamo parlato di SQLInjection, cross-site scripting e gestione delle password.

Per quanto riguarda quest’ultima parte ho fatto una distinzione a seconda dei casi d’uso della password in stessa. Se infatti la password è necessaria per implementare un nostro meccanismo di login, allora l’ideale è salvarla sotto forma di HASH, magari con l’aggiunta di un salt (Password Storage Cheat Sheet). Ma se è necessario poter decifrare la password per usarla ad esempio durante l’autenticazione ad un servizio terzo (un server database, di posta o un’API ReST) ovviamente questa soluzione non è praticabile.

In questo caso è necessario salvare la password cifrandola con un algoritmo reversibile come AES. Il problema è: dove metto la chiave usata per la cifratura? Questa è proprio la domanda che mi ha fatto uno dei partecipanti al seminario.

Il problema è che non c’è una risposta risposta che vada bene in ogni caso possibile. Questo infatti è un caso di defensive programming, cioè un tipo progettazione del codice dove si cerca di adottare strategie che facciano funzionare il programma in tutti i casi anche se non sappiamo esattamente il tipo di problema da cui ci stiamo difendendo.

In questo caso dobbiamo fare una serie di ragionamenti, per esempio se la password è salvata sul database la chiave crittografica dovrà stare da un’altra parte. Il ragionamento generale è che password è chiave crittografica devono stare in due posti diversi, in modo che se uno risulti compromesso possiamo sperare che l’altro non lo sia.

Un’altra soluzione potrebbe essere salvare la chiave direttamente nell’eseguibile, magari cercando di nasconderla in qualche modo, per esempio in esadecimale o come array di byte. Questo renderebbe il recupero della chiave un po’ più complicato, ma per un attaccante motivato non è certo un ostacolo insormontabile, in più lascerebbe la chiave visibile a chiunque abbia accesso ai sorgenti (di certo non è una buona idea nei progetti Open Source).

In alcuni casi è possibile usare delle apposite API del sistema operativo. Su Windows c’è DPAPI (Data Protection Application Programming Interface) che fondamentalmente usa la password dell’utente di Windows come master password. Il limite è che chi cifra la password deve avere le stesse credenziali di chi la decifra.

Se poi l’applicazione usa già servizi cloud, sia Microsoft che Amazon offrono servizi di storage sicuro (Amazon KMS o Azure Key Vault).
Insomma come già dicevo durante il Webinar non esiste una soluzione semplice ma è necessario valutare la migliore strategia che risolva il nostro problema.

Happy coding.