Linee guida per la scrittura di codice protetto
Nelle linee guida riportate di seguito vengono illustrate alcune tecniche per la scrittura di codice protetto.
Obbligatorio
Utilizzare strumenti di analisi del codice.
In Visual Studio Premium sono disponibili strumenti di analisi del codice che aumentano notevolmente le probabilità di individuare bug di sicurezza nel codice, con evidenti vantaggi in termini di efficienza e facilità d'uso. Per ulteriori informazioni, vedere uno degli argomenti indicati di seguito.
Effettuare una revisione per rilevare problemi di sicurezza.
L'obiettivo di qualsiasi verifica della sicurezza consiste nell'ottimizzare la sicurezza dei prodotti già rilasciati attraverso aggiornamenti oppure evitare che vengano rilasciati nuovi prodotti finché non viene raggiunto il livello di sicurezza desiderato.
Non eseguire una revisione approssimativa del codice. Prepararsi in anticipo e partire dalla creazione di una classificazione dei rischi per evitare che i componenti del team sprechino tempo prezioso. Stabilire un ordine di priorità del codice da sottoporre alla verifica più accurata della sicurezza e dei bug di sicurezza da correggere.
Specificare in modo dettagliato gli elementi da verificare durante la revisione. Una ricerca mirata consente di identificare i problemi con maggiore facilità. Approfondire ulteriormente la verifica se il team individua un numero particolarmente elevato di bug di sicurezza in un'area specifica. Questa circostanza indica probabilmente un problema correlato all'architettura che deve essere corretto. Se non viene rilevato alcun bug di sicurezza, è molto probabile che la revisione non sia stata effettuata correttamente.
Considerare la revisione per la verifica della sicurezza come parte della stabilizzazione di ogni fase di sviluppo e come una strategia di promozione più ampia della linea di prodotti stabilita dalla dirigenza.
Utilizzare un elenco di controllo per eseguire una verifica della sicurezza.
Indipendentemente dal ruolo rivestito nel team di sviluppo software, è utile disporre di un elenco di controllo da seguire per far sì che il codice e la progettazione soddisfino un livello minimo stabilito.
Convalidare tutto l'input utente.
Se si consente all'applicazione di accettare input diretti o indiretti dell'utente, è necessario che l'input venga convalidato prima di essere utilizzato. Gli utenti malintenzionati tenteranno di rendere inutilizzabile l'applicazione sviluppata modificando l'input per rappresentare dati non validi. La prima regola dell'input utente è la seguente: tutto l'input deve essere considerato non valido fino a prova contraria.
Utilizzare con cautela le espressioni regolari per convalidare l'input utente. Per espressioni complesse come gli indirizzi di posta elettronica, è facile pensare che si stia svolgendo una convalida completa anche quando in realtà non viene effettuata. Chiedere ai propri colleghi di revisionare tutte le espressioni regolari.
Convalidare in modo sicuro tutti i parametri delle API (Application Programming Interface) esportate e pubbliche.
Assicurarsi che tutti i parametri delle API esportate e pubbliche siano validi. Verificare, ad esempio, gli input che risultano coerenti ma che non sono compresi nell'intervallo di valori consentiti, ad esempio dimensioni eccessive del buffer. Non utilizzare le asserzioni per verificare i parametri relativi alle API esportate in quanto esse verranno rimosse nella build di rilascio.
Utilizzare le API di crittografia di Windows.
Anziché scrivere un software di crittografia personalizzato, utilizzare l'API di crittografia di Windows già disponibile. Attraverso questo tipo di API Microsoft, gli sviluppatori hanno la possibilità di concentrarsi sulla compilazione di applicazioni. È importante ricordare, infatti, che la crittografia risolve molto bene una piccola serie di problemi e viene spesso utilizzata con modalità diverse da quelle per cui è stata creata. Per ulteriori informazioni, vedere la pagina di riferimento relativa alla crittografia in MSDN Library.
Operazioni da evitare
Sovraccarichi del buffer.
Un sovraccarico del buffer statico si verifica quanto un buffer dichiarato sullo stack viene sovrascritto mediante la copia di dati più grandi del buffer stesso. Le variabili dichiarate sullo stack si trovano accanto all'indirizzo per il chiamante della funzione. I sovraccarichi del buffer possono verificarsi anche nell'heap e sono altrettanto pericolosi. La causa più frequente è il passaggio di input utente non controllati a una funzione come strcpy che comporta la sovrascrittura dell'indirizzo restituito della funzione da parte di un indirizzo scelto da chi effettua l'attacco. Per impedire i sovraccarichi del buffer, generalmente è sufficiente scrivere un'applicazione affidabile.
Asserzioni per controllare l'input esterno.
Le asserzioni non vengono compilate nelle versioni per la vendita. È opportuno quindi non utilizzarle per verificare gli input esterni. È necessario verificare la validità di tutti i parametri relativi a metodi e funzioni esportate, dell'intero input utente e di tutti i dati su file e socket, respingendoli se contengono errori.
Coppie di ID utente e password specificate a livello di codice (hard-coded).
Non utilizzare password specificate a livello di codice. Modificare il programma di installazione per far sì che al momento della creazione di account utente incorporati, all'amministratore vengano chieste password sicure per ogni account. In questo modo sarà possibile garantire la sicurezza dei sistemi a livello di produzione dei clienti.
Utilizzo della crittografia per risolvere tutti i problemi di sicurezza.
La crittografia risolve ottimamente un determinato set di problemi ed è spesso utilizzata in modi per i quali non è stata concepita.
URL e percorsi file canonici.
Evitare situazioni in cui il percorso di un file o di un URL è importante. Utilizzare ACL del file system piuttosto che regole basate su nomi di file canonici.
Operazioni consigliate
Esaminare tutti i problemi di sicurezza precedenti rilevati nell'applicazione.
Acquisire familiarità con gli errori di sicurezza commessi in passato. Il codice viene spesso scritto sulla base di modelli ricorrenti, pertanto la presenza di un bug introdotto da una determinata persona in una posizione potrebbe indicare lo stesso bug introdotto da altre persone in altre posizioni.
Esaminare tutti i percorsi degli errori.
Spesso il codice nei percorsi degli errori non viene testato in modo appropriato e non comporta la pulizia di tutti gli oggetti, ad esempio i blocchi o la memoria allocata. Esaminare con attenzione tali percorsi e, se necessario, creare test di inserimento di errori per eseguire e verificare il codice. Per ulteriori informazioni, vedere la sezione relativa alla convalida degli input delle linee guida per la sicurezza delle applicazioni Web e l'omonima sezione della pagina relativa alla verifica dell'architettura e della progettazione ai fini della sicurezza in MSDN Library.
Operazioni non consigliate
Privilegi dell'amministratore per l'esecuzione dell'applicazione.
Le applicazioni devono essere eseguite con il livello di privilegio più basso per consentire il completamento del lavoro. Se un utente malintenzionato rileva una vulnerabilità nel sistema di sicurezza e inserisce porzioni di codice nel processo, il codice dannoso verrà eseguito con gli stessi privilegi del processo host. Se il processo viene eseguito come amministratore, il codice dannoso verrà eseguito come amministratore. Per ulteriori informazioni, vedere la pagina relativa allo sviluppo di software in Visual Studio .NET con privilegi non amministrativi in MSDN Library.