Linee guida per la generazione di codice sicuro
Nella maggior parte dei casi, per proteggere il codice delle applicazioni è sufficiente l'infrastruttura implementata da .NET. In alcuni casi è tuttavia necessaria una sicurezza aggiuntiva specifica per l'applicazione, creata mediante l'estensione del sistema di sicurezza o tramite metodi ad hoc.
L'uso delle autorizzazioni imposte da .NET e di altre imposizioni nel codice, consente di creare barriere che impediscono l’accesso alle informazioni da parte di malware indesiderato o l'esecuzione di altre operazioni non desiderate. È inoltre necessario raggiungere un compromesso tra sicurezza e usabilità del codice in tutti gli scenari d'uso di codice attendibile.
In questa panoramica vengono descritti i diversi metodi di progettazione del codice per l'uso del sistema di sicurezza.
Protezione dell'accesso alle risorse
Durante la progettazione e la scrittura del codice, è necessario proteggere e limitare l'accesso del codice alle risorse, soprattutto quando si usa o chiama codice di origine sconosciuta. Le tecniche seguenti consentono di verificare che il codice sia sicuro:
Non usare Sicurezza per l'accesso al codice (CAS, Code Access Security).
Non usare codice parzialmente attendibile.
Non usare l'attributo AllowPartiallyTrustedCaller (APTCA).
Non usare Servizi remoti .NET.
Non usare DCOM (Distributed Component Object Model).
Non utilizzare formattori binari.
La sicurezza dall'accesso di codice e il codice trasparente per la sicurezza non sono supportati come limiti di sicurezza con codice parzialmente attendibile. Non è consigliabile caricare ed eseguire codice di origine sconosciuta in assenza di misure di sicurezza alternative. Le misure di protezione alternative sono:
Virtualizzazione
AppContainers
Utenti e autorizzazioni del sistema operativo (SO)
Contenitori Hyper-V
Codice indipendente dalla sicurezza
Il codice indipendente dalla sicurezza non ha elementi espliciti in comune con il sistema di sicurezza e viene eseguito a prescindere dalle autorizzazioni ricevute Anche se le applicazioni che non riescono a intercettare eccezioni associate alle operazioni protette, come l'uso di file o le operazioni in rete, possono avere come effetto eccezioni non gestite, il codice indipendente dalla sicurezza è comunque in grado di sfruttare le tecnologie di sicurezza di .NET.
Una libreria indipendente dalla sicurezza dispone di caratteristiche speciali che è necessario comprendere. Si supponga che la libreria fornisca elementi API che usano file o chiamano codice non gestito. Se il codice non dispone dell'autorizzazione corrispondente, non sarà eseguito come descritto. Tuttavia, anche al codice viene concessa l'autorizzazione, il codice delle applicazioni da cui tale codice viene chiamato deve disporre della stessa autorizzazione per funzionare. Se il codice chiamante non dispone dell'autorizzazione appropriata, viene visualizzato SecurityException come risultato di chiamate nello stack di sicurezza dall’accesso al codice.
Codice di applicazione che non è un componente riutilizzabile
Se il codice è parte di un'applicazione che non verrà richiamata da altro codice, la sicurezza è semplice e potrebbe non essere necessario scrivere codice speciale. Tenere comunque presente che il codice può essere chiamato da codice dannoso. Anche se la sicurezza per l'accesso al codice può impedire a codice dannoso di accedere alle risorse, con questo codice è comunque possibile leggere i valori contenuti nei campi o nelle proprietà che possono rappresentare informazioni sensibili.
Se inoltre il codice accetta input da Internet o da altre fonti inaffidabili, è opportuno evitare input dannosi.
Wrapper gestiti nell'implementazione di codice nativo
In genere, in uno scenario di questo tipo, viene implementata una funzionalità utile nel codice nativo da rendere disponibile per il codice gestito. I wrapper gestiti possono essere scritti in modo semplice usando platform invoke o l'interoperabilità COM. Per la riuscita di questa operazione è tuttavia necessario che i chiamanti dei wrapper dispongano di diritti per il codice non gestito. In base ai criteri predefiniti, questo significa che il codice scaricato da una rete Intranet o da Internet non funzionerà con i wrapper.
Invece di assegnare i diritti di codice non gestito a tutte le applicazioni che impiegano questi wrapper, è preferibile fornire questi diritti solo al codice wrapper. Se la funzionalità sottostante non espone alcuna risorsa e l'implementazione è probabilmente sicura, per il wrapper è sufficiente l'asserzione dei diritti, che consente la chiamata tramite codice. Quando sono coinvolte le risorse, il codice della sicurezza deve essere analogo a quello di libreria descritto nella sezione successiva. Poiché il wrapper può esporre i chiamanti a queste risorse, la verifica attenta della sicurezza del codice nativo è necessaria e costituisce uno dei compiti del wrapper.
Codice di libreria che espone risorse protette
L’approccio seguente è il più efficace e pertanto potenzialmente pericoloso, se eseguito in modo non corretto, della codifica della sicurezza: la libreria funge da interfaccia per l'accesso tramite codice ad alcune risorse non altrimenti disponibili, così come le classi di .NET impongono le autorizzazioni relative alle risorse che usano. Se si espone una risorsa, è necessario per prima cosa esigere tramite codice l'autorizzazione adeguata alla risorsa (in altre parole, eseguire un controllo di sicurezza) e quindi eseguire un'asserzione dei relativi diritti per eseguire l'operazione vera e propria.