Condividi tramite


Procedure di sicurezza consigliate per lo sviluppo di giochi

Questo articolo illustra le procedure consigliate da usare nello sviluppo di giochi.

Introduzione

Un numero crescente di persone giocano giochi e giochi online con contenuti creati dall'utente. Questo, combinato con l'aumento della sicurezza del sistema operativo Microsoft Windows, significa che i giochi sono un obiettivo crescente e più allettante per gli utenti malintenzionati di sfruttare. Gli sviluppatori di giochi devono porre un forte accento su come assicurarsi che i giochi rilasciati non creino nuovi buchi di sicurezza per gli utenti malintenzionati da sfruttare. Gli sviluppatori di giochi hanno una responsabilità e un interesse per impedire che i computer dei clienti vengano violati da dati di rete dannosi, modifiche degli utenti o manomissioni. Se viene sfruttata una vulnerabilità, potrebbe comportare la perdita di clienti e/o denaro. Questo articolo descrive e illustra alcuni metodi e strumenti comuni per aumentare la sicurezza del codice senza aumentare il tempo di sviluppo.

I tre errori più comuni eseguiti da un team di sviluppo durante il rilascio di un prodotto sono:

Ognuno degli errori elencati non è solo comune, ma è facilmente correggibile senza modifiche significative nel carico di lavoro di sviluppo, negli standard di codifica o nelle funzionalità.

Esempi di codice non sicuro

Di seguito è riportato un semplice esempio di tutte le operazioni necessarie per consentire a un utente malintenzionato di eseguire un attacco di sovraccarico del buffer:

void GetPlayerName(char *pDatafromNet)
{
    char playername[256]; 
    strncpy(playername, pDatafromNet, strlen(pDatafromNet));

    // ...
}

In superficie, questo codice sembra ok: chiama una funzione sicura, dopo tutto. I dati della rete sono copiati in un buffer di 256 byte. La funzione strncpy si basa sulla ricerca di un carattere di terminazione NULL nella stringa di origine o è limitata dal numero di buffer specificato. Il problema è che le dimensioni del buffer non sono corrette. Se i dati dalla rete non vengono convalidati o le dimensioni del buffer non sono corrette (come in questo esempio), un utente malintenzionato potrebbe semplicemente fornire un buffer di grandi dimensioni per sovrascrivere i dati dello stack, dopo il termine del buffer, con tutti i dati nel pacchetto di rete. Ciò consentirebbe all'utente malintenzionato di eseguire codice arbitrario sovrascrivendo il puntatore all'istruzione e modificando l'indirizzo restituito. La lezione più semplice di questo esempio consiste nel non considerare mai attendibile l'input fino a quando non viene verificato.

Anche se i dati non provengono inizialmente dalla rete, esiste comunque un rischio potenziale. Lo sviluppo di giochi moderni richiede molte persone che progettano, sviluppano e testano la stessa codebase. Non esiste alcun modo per sapere come verrà chiamata la funzione in futuro. Chiedersi sempre da dove provengono i dati e cosa potrebbe essere un utente malintenzionato a controllare? Mentre gli attacchi basati sulla rete sono i più comuni, non sono gli unici metodi di creazione di buchi di sicurezza. Un utente malintenzionato potrebbe creare un mod o modificare un file salvato in modo da aprire un buco di sicurezza? Che ne dici di file audio e immagine forniti dall'utente? Le versioni dannose di questi file potrebbero essere pubblicate su Internet e creare rischi pericolosi per la sicurezza per i clienti.

Come nota laterale, usare strsafe.h o Cassaforte CRT anziché strncpy per correggere l'esempio. Cassaforte CRT è una revisione completa della sicurezza del runtime C e include parte di Visual Studio 2005. Altre informazioni su Cassaforte CRT sono disponibili in Miglioramenti della sicurezza in CRT di Michael Howard.

Modi per migliorare la sicurezza

Esistono diversi modi per migliorare la sicurezza nel ciclo di sviluppo. Ecco alcuni dei modi migliori:

Lettura della sicurezza

Il libro Writing Secure Code, Second Edition di Michael Howard e David LeBlanc, fornisce una spiegazione approfondita e chiara delle strategie e dei metodi di prevenzione degli attacchi e della mitigazione degli exploit. A partire dai metodi di progettazione della sicurezza in una versione alle tecniche per la protezione delle applicazioni di rete, il libro illustra tutti gli aspetti che uno sviluppatore di giochi deve aiutare a proteggere se stessi, i propri prodotti e i propri clienti da utenti malintenzionati. Il libro può essere usato per infondere una cultura della sicurezza in uno studio di sviluppo. Non considerare solo la sicurezza del codice come un problema dello sviluppatore o il problema di un tester. Si pensi alla sicurezza come a un intero team, dal program manager alla finestra di progettazione allo sviluppatore al tester, dovrebbe pensare a quando lavorano su un progetto. Più gli occhi che fanno parte del processo di revisione, maggiore è la possibilità di intercettare un buco di sicurezza prima del rilascio.

La scrittura di codice sicuro, seconda edizione è disponibile in Microsoft Press Store e altre informazioni di sicurezza generali sono disponibili in Bloccang Off Future Attacks by Reducing Attack Surface di Michael Howard.

Michael Howard, David LeBlanc e John Viega hanno scritto un altro libro sul tema che copre tutti i sistemi operativi comuni e i linguaggi di programmazione intitolati 19 Deadly Sins of Software Security.

Le presentazioni di sicurezza incentrate sui giochi sono disponibili nella pagina di download delle presentazioni per sviluppatori Microsoft XNA.

Analisi di modellazione delle minacce

Un'analisi di modellazione delle minacce è un buon modo per valutare la sicurezza del sistema, non in un linguaggio specifico o usando uno strumento, ma in un metodo end-to-end ampio che può essere eseguito in poche riunioni. Se implementato correttamente, un modello di thread può identificare tutti i punti di forza e i punti deboli di un sistema, senza aggiungere carichi di lavoro significativi o tempo di riunione al progetto. Il metodo di modellazione delle minacce sottolinea anche l'idea di valutare la sicurezza del sistema prima e durante il processo di sviluppo per garantire che venga eseguita una valutazione completa concentrandosi sulle funzionalità più rischiose. Può essere considerato come un profiler per la sicurezza. Non essendo basato su un linguaggio specifico o basandosi su uno strumento specifico, la modellazione delle minacce può essere usata in qualsiasi studio di sviluppo che lavora su qualsiasi progetto in qualsiasi genere. La modellazione delle minacce è anche un ottimo metodo per rafforzare l'idea che la sicurezza sia responsabilità di tutti e non il problema di qualcun altro.

Quando si modellano le minacce, prestare particolare attenzione a:

  • Origini dati UDP
  • Origini dati che non richiedono l'autenticazione
  • Origini dati che sono spesso e normalmente sondate come parte della raccolta di informazioni su larga scala
  • Qualsiasi capacità di un client di inviare direttamente dati ad altri client

Queste sono le aree che hanno un buon potenziale per le debolezze della sicurezza.

Per altre informazioni sulla modellazione delle minacce, vedere Modellazione delle minacce nel Centro sviluppo per la sicurezza MSDN e nel libro Modellazione delle minacce di Frank Swiderski e Window Snyder.

Prevenzione dell'esecuzione dei dati (/NX)

Uno strumento recente nella mitigazione di più exploit è la prevenzione dell'esecuzione dei dati (DEP). Se si include l'opzione /NX nel comando di compilazione, Visual Studio contrassegnerà le pagine di memoria con flag che indicano se il codice ha il diritto di eseguire o meno. Qualsiasi programma che tenta di eseguire in una pagina di memoria non contrassegnata con l'autorizzazione EXECUTE causerà una terminazione forzata del programma. La prevenzione viene applicata a livello di processore e influirà sugli sviluppatori che usano codice di modifica automatica o compilatori nativi del linguaggio JIT. Attualmente, solo i processori Athlon64 e Opteron di AMD e i processori Itanium e Intel 4 più recenti supportano la prevenzione dell'esecuzione, ma è previsto che tutti i processori a 32 bit e a 64 bit supportino la prevenzione dell'esecuzione in futuro. Uno schema di protezione della copia usato da uno sviluppatore può essere interessato dalla prevenzione dell'esecuzione, ma Microsoft ha lavorato con i fornitori di protezione della copia per ridurre al minimo l'impatto. È consigliabile usare DEP.

Per altre informazioni su DEP, vedere Prevenzione dell'esecuzione dei dati.

Il controllo di sicurezza del buffer (/GS) e l'immagine hanno Cassaforte gestori eccezioni (/SAFE edizione Standard H)

Il controllo di sicurezza del buffer, specificato dal flag del compilatore /GS e Image ha Cassaforte gestori eccezioni, specificati dal flag del linker /SAFE edizione Standard H (implementato prima in Visual Studio .NET 2003), può semplificare il lavoro dello sviluppatore di proteggere il codice.

L'uso del flag /GS fa sì che il compilatore costruisca un controllo per alcune forme di sovraccarico del buffer basato su stack che potrebbero essere sfruttate per sovrascrivere l'indirizzo restituito di una funzione. L'uso di /GS non rileverà ogni potenziale sovraccarico del buffer e non deve essere considerato un catch-all, ma una buona tecnologia di difesa avanzata.

L'uso del flag /SAFE edizione Standard H indicherà al linker di generare solo un eseguibile o una DLL se può generare anche una tabella dei gestori di eccezioni sicuri del file eseguibile o della DLL. Cassaforte la gestione strutturata delle eccezioni (Cassaforteedizione Standard H) elimina la gestione delle eccezioni come destinazione di attacchi di sovraccarico del buffer assicurandosi che, prima che venga inviata un'eccezione, il gestore eccezioni viene registrato nella tabella delle funzioni che si trova all'interno del file di immagine. Questi vantaggi di protezione sono abilitati con Windows XP SP2, Windows Server 2003, Windows Vista e Windows 7. Anche per il corretto funzionamento di /SAFE edizione Standard H, deve essere usato in un metodo all-or-nothing. Tutte le librerie contenenti codice associato a un eseguibile o a una DLL devono essere compilate con /SAFE edizione Standard H o la tabella non verrà generata.

Altre informazioni su Buffer Security Check (/GS) e Image include Cassaforte gestori eccezioni (/SAFE edizione Standard H) sono disponibili in MSDN.

Vedere anche informazioni sul flag /SDL di Microsoft Visual Studio 2012 e sui miglioramenti di Visual Studio 2012 per il flag /GS.

PREfast

PREfast è uno strumento gratuito offerto da Microsoft che analizza i percorsi di esecuzione in C o C++ compilati per trovare bug in fase di esecuzione. PREfast opera usando tutti i percorsi di esecuzione in tutte le funzioni e valutando ogni percorso per i problemi. Usato originariamente per sviluppare driver e altro codice kernel, questo strumento può aiutare gli sviluppatori di giochi a risparmiare tempo eliminando alcuni bug difficili da trovare o vengono ignorati dal compilatore. L'uso di PREfast è un ottimo modo per ridurre il carico di lavoro e concentrare gli sforzi del team di sviluppo e del team di test. PREfast è disponibile in Visual Studio Team Suite e Visual Studio Team Edition per sviluppatori software come analisi del codice, abilitata dall'opzione /analyze del compilatore. Questa opzione è disponibile anche nella versione gratuita del compilatore fornito con Windows Software Development Kit.

Nota

Visual Studio 2012 supporta /analyze in tutte le edizioni. Per altre informazioni sulla disponibilità dell'analisi del codice in tutte le edizioni di Visual Studio, vedere Novità dell'analisi del codice.

 

Tramite l'uso dell'annotazione dell'intestazione (in particolare per gli argomenti del puntatore del buffer), PREfast può esporre problemi aggiuntivi, ad esempio i bug di sovrascrittura della memoria, un'origine comune di arresti anomali e potenziali vulnerabilità di sicurezza. Questa operazione viene eseguita usando il linguaggio sal (Standard Annotation Language), che è una forma di mark-up per i prototipi di funzione C/C++ che forniscono informazioni aggiuntive sulla semantica degli argomenti del puntatore previsto e la correlazione con parametri di lunghezza, dimensioni del buffer dichiarate e così via. Tutte le intestazioni per i sistemi operativi Windows vengono annotate e l'aggiunta del mark-up SAL nelle intestazioni dell'API pubblica nelle proprie librerie consente a PREfast di eseguire controlli più dettagliati e aggressivi nel codice client per tali API. Per un'introduzione a SAL e collegamenti ad altre informazioni, vedere il post di blog di Michael Howard, "A Brief Introduction to the Standard Annotation Language (SAL)".

Verifica dell'applicazione Windows

Windows Application Verifier, o AppVerifier, può aiutare i tester fornendo più funzioni in un unico strumento. AppVerifier è uno strumento sviluppato per rendere più testabili gli errori di programmazione comuni. AppVerifier può controllare i parametri passati alle chiamate API, inserire input errato per controllare la capacità di gestione degli errori e registrare le modifiche al Registro di sistema e al file system. AppVerifier può anche rilevare i sovraccarichi del buffer nell'heap, verificare che sia stato definito correttamente un elenco di Controllo di accesso (ACL) e applicare l'uso sicuro delle API socket. Anche se non esaustivo, AppVerifier può essere uno strumento nella casella degli strumenti del tester per consentire a uno studio di sviluppo di rilasciare un prodotto di qualità.

Per altre informazioni su Application Verifier, vedere Application Verifier and Using Application Verifier within Your Software Development Lifecycle (Verifica applicazione e uso di Application Verifier all'interno del ciclo di vita di sviluppo software) su MSDN.

Test fuzz

Il test fuzz è un metodo semi-automatizzato di test che può migliorare le metodologie di test correnti. L'idea centrale alla base dei test fuzz consiste nell'eseguire una valutazione completa di tutti gli input inserendo dati casuali per vedere quali interruzioni; include tutti i dati di rete, i mod e i giochi salvati e così via. I test fuzz sono abbastanza facili da eseguire. È sufficiente modificare i file ben formati o i dati di rete inserendo byte casuali, capovolgendo byte adiacenti o negando valori numerici. 0xff, 0xffff, 0xffffffff, 0x00, 0x0000, 0x00000000 e 0x80000000 sono valori validi per esporre i fori di sicurezza durante i test fuzz. È possibile osservare le combinazioni di interazione risultanti usando AppVerifier. Anche se la fuzzing non è esaustiva, è facile da implementare e automatizzare e può rilevare i bug più elusivi e imprevedibili.

Per altre informazioni sui test fuzz, vedi la presentazione di Gamefest 2007 Passaggi pratici in Game Security.

Firma Authenticode

Authenticode è un metodo per garantire che i file eseguibili, i file DLL e i pacchetti di Windows Installer (file con estensione msi) ricevuti dall'utente non vengano alterati da ciò che uno sviluppatore ha rilasciato. Usando una combinazione di principi crittografici, entità attendibili e standard di settore, Authenticode verifica l'integrità del contenuto eseguibile. Microsoft fornisce un'API crittografica, CryptoAPI, che può essere usata per rilevare automaticamente la manomissione del codice firmato. Se si verifica una perdita di sicurezza dopo un rilascio, è possibile revocare un certificato e tutto il codice firmato con tale certificato interromperà l'autenticazione. La revoca di un certificato revoca la convalida di tutti i titoli firmati con tale certificato. Windows è stato progettato per funzionare con la firma di Authenticode e avvisa un utente di codice non firmato, in situazioni specifiche, che potrebbero esporre il PC di un utente all'attacco.

Authenticode non deve essere considerato un metodo per eliminare i problemi di sicurezza, ma un metodo di rilevamento della manomissione dopo il rilascio di un eseguibile. Un eseguibile o una DLL che contiene un problema di sicurezza sfruttabile può essere firmato e verificato tramite Authenticode, ma continuerà a introdurre il problema di sicurezza al nuovo sistema. Solo dopo che un prodotto o un aggiornamento è stato verificato per essere sicuro, il codice deve essere firmato per garantire agli utenti che hanno una versione che non è stata manomessa.

Anche se uno sviluppatore ritiene che non vi sia alcuna minaccia per le versioni modificate, altre tecnologie e servizi si basano su Authenticode. La firma del codice è facile da integrare e automatizzare; non c'è motivo per gli sviluppatori di non avere le loro versioni firmate.

Per altre informazioni sulla firma di Authenticode, vedere Firma Authenticode per sviluppatori di giochi.

Ridurre al minimo i privilegi

In generale, i processi devono essere eseguiti con il set minimo di privilegi necessari per funzionare. In Windows Vista e Windows 7, questa operazione viene eseguita usando il controllo dell'account utente, consentendo l'esecuzione del gioco come utente standard anziché come amministratore. Per Windows XP, in genere i giochi sono sempre in esecuzione come amministratore. Anche in Windows Vista e Windows 7, a volte è necessario elevare i diritti di amministratore completi per alcune operazioni specifiche.

Nei casi in cui il processo viene eseguito con diritti amministrativi completi, in genere sono richiesti solo pochi diritti oltre quelli di un utente standard. l'accesso Amministrazione istrativo include molti diritti che non sono richiesti dal codice legittimo, ma possono essere usati da un utente malintenzionato, attraverso alcuni punti deboli nel processo. Esempi di tali diritti includono edizione Standard_TAKE_OWNERSHIP, edizione Standard_DEBUG, edizione Standard_CREATE_TOKEN, edizione Standard_ASSIGNPRIMARYTOKEN, edizione Standard_TCB, edizione Standard_ edizione Standard CURITY, edizione Standard_LOAD_DRIVER, edizione Standard_SYSTEMTIME, edizione Standard_BACKUP, edizione Standard_RESTORE, edizione Standard_SHUTDOWN e edizione Standard_AUDIT (vedere Costanti priviledge).

Mentre un processo non può ottenere più diritti una volta avviato, può facilmente rinunciare ai diritti. All'avvio, il processo può usare immediatamente le API Win32 per rimuovere i diritti non necessari.

Utilizzare le funzionalità di Sicurezza di Windows

Windows Vista e Windows 7 includono una serie di nuove funzionalità che migliorano la sicurezza del codice. Controllo account utente è certamente quello più importante da comprendere e adottare, ma ci sono anche altre funzionalità. Oltre alle tecnologie Windows XP SP2, ad esempio Windows Firewall, Prevenzione esecuzione dati, Controllo sicurezza buffer e Cassaforte gestori eccezioni disponibili anche in Windows Vista e Windows 7, sono disponibili tre funzionalità di sicurezza più recenti da considerare:

  • Funzionalità di randomizzazione del layout dello spazio di indirizzi esplicito. Questa opzione è abilitata collegando con l'opzione /DYNAMICBA edizione Standard in Visual Studio 2005 Service Pack 1 o Visual Studio 2008. Questo fa sì che il sistema eseghi in modo casuale le posizioni di molte DLL del sistema chiave nello spazio di elaborazione, rendendo molto più difficile scrivere programmi di attacco sfruttabili che si propagano su larga scala in Internet. Questo flag del linker viene ignorato da Windows XP e dalle versioni precedenti di Windows.
  • Il danneggiamento dell'heap può causare un'intera classe di exploit di sicurezza, quindi il sistema di memoria di Windows Vista e Windows 7 supporta ora una modalità che termina il processo se viene rilevato il danneggiamento dell'heap. La chiamata di HeapSetInformation con HeapEnableTermianteOnCorruption acconsente a questo comportamento. Questa chiamata non riesce in Windows XP e nella versione precedente di Windows.
  • Durante la scrittura di servizi, possono essere configurati usando una nuova funzionalità per specificare quali privilegi sono effettivamente necessari, nonché limitare l'accesso alle risorse a un SID specifico. Questa operazione viene eseguita tramite ChangeSeviceConfig2, usando edizione StandardRVICE_CONFIG_REQUIRED_PRIVILEGES_INFO e edizione StandardRVICE_CONFIG_edizione StandardRVICE_SID_INFO.

Riepilogo

Lo sviluppo di un gioco per il marketplace attuale e futuro è costoso e richiede molto tempo. Il rilascio di un gioco con problemi di sicurezza in definitiva costerà più denaro e tempo per risolvere correttamente. Pertanto, è nell'interesse di tutti gli sviluppatori di giochi integrare strumenti e tecniche per attenuare gli exploit di sicurezza prima del rilascio.

Le informazioni contenute in questo articolo sono solo un'introduzione a ciò che uno studio di sviluppo può fare per aiutare se stessi e i clienti. Altre informazioni sulle procedure di sicurezza generali e sulle informazioni sulla sicurezza sono disponibili nel Centro per sviluppatori microsoft per la sicurezza.